l3lab/ntp-mathlib huggingface dataset:
/-- Given a finpartition `P` of `a` and finpartitions of each part of `P`, this yields the
finpartition of `a` obtained by juxtaposing all the subpartitions. -/
@[simps]
def bind (P : Finpartition a) (Q : ∀ i ∈ P.parts, Finpartition i) : Finpartition a
    where
  parts := P.parts.attach.biUnion fun i ↦ (Q i.1 i.2).parts
  supIndep := by
    rw [supIndep_iff_pairwiseDisjoint]
    rintro a ha b hb h
    rw [Finset.mem_coe, Finset.mem_biUnion] at ha hb
    obtain ⟨⟨A, hA⟩, -, ha⟩ := ha
    obtain ⟨⟨B, hB⟩, -, hb⟩ := hb
    

Proof state:
case intro.mk.intro.intro.mk.intro
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a✝ b✝ c : α
P✝ : Finpartition a✝
Q✝ : (i : α) → i ∈ P✝.parts → Finpartition i
P : Finpartition a✝
Q : (i : α) → i ∈ P.parts → Finpartition i
a b : α
h : a ≠ b
A : α
hA : A ∈ P.parts
ha : a ∈ (Q ↑{ val := A, property := hA } (_ : ↑{ val := A, property := hA } ∈ P.parts)).parts
B : α
hB : B ∈ P.parts
hb : b ∈ (Q ↑{ val := B, property := hB } (_ : ↑{ val := B, property := hB } ∈ P.parts)).parts
⊢ (Disjoint on id) a b

Next tactic:
obtain rfl | hAB := eq_or_ne A B
/-- Given a finpartition `P` of `a` and finpartitions of each part of `P`, this yields the
finpartition of `a` obtained by juxtaposing all the subpartitions. -/
@[simps]
def bind (P : Finpartition a) (Q : ∀ i ∈ P.parts, Finpartition i) : Finpartition a
    where
  parts := P.parts.attach.biUnion fun i ↦ (Q i.1 i.2).parts
  supIndep := by
    rw [supIndep_iff_pairwiseDisjoint]
    rintro a ha b hb h
    rw [Finset.mem_coe, Finset.mem_biUnion] at ha hb
    obtain ⟨⟨A, hA⟩, -, ha⟩ := ha
    obtain ⟨⟨B, hB⟩, -, hb⟩ := hb
    obtain rfl | hAB := eq_or_ne A B
    · 

Proof state:
case intro.mk.intro.intro.mk.intro.inl
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a✝ b✝ c : α
P✝ : Finpartition a✝
Q✝ : (i : α) → i ∈ P✝.parts → Finpartition i
P : Finpartition a✝
Q : (i : α) → i ∈ P.parts → Finpartition i
a b : α
h : a ≠ b
A : α
hA : A ∈ P.parts
ha : a ∈ (Q ↑{ val := A, property := hA } (_ : ↑{ val := A, property := hA } ∈ P.parts)).parts
hB : A ∈ P.parts
hb : b ∈ (Q ↑{ val := A, property := hB } (_ : ↑{ val := A, property := hB } ∈ P.parts)).parts
⊢ (Disjoint on id) a b

Next tactic:
exact (Q A hA).disjoint ha hb h
/-- Given a finpartition `P` of `a` and finpartitions of each part of `P`, this yields the
finpartition of `a` obtained by juxtaposing all the subpartitions. -/
@[simps]
def bind (P : Finpartition a) (Q : ∀ i ∈ P.parts, Finpartition i) : Finpartition a
    where
  parts := P.parts.attach.biUnion fun i ↦ (Q i.1 i.2).parts
  supIndep := by
    rw [supIndep_iff_pairwiseDisjoint]
    rintro a ha b hb h
    rw [Finset.mem_coe, Finset.mem_biUnion] at ha hb
    obtain ⟨⟨A, hA⟩, -, ha⟩ := ha
    obtain ⟨⟨B, hB⟩, -, hb⟩ := hb
    obtain rfl | hAB := eq_or_ne A B
    · exact (Q A hA).disjoint ha hb h
    · 

Proof state:
case intro.mk.intro.intro.mk.intro.inr
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a✝ b✝ c : α
P✝ : Finpartition a✝
Q✝ : (i : α) → i ∈ P✝.parts → Finpartition i
P : Finpartition a✝
Q : (i : α) → i ∈ P.parts → Finpartition i
a b : α
h : a ≠ b
A : α
hA : A ∈ P.parts
ha : a ∈ (Q ↑{ val := A, property := hA } (_ : ↑{ val := A, property := hA } ∈ P.parts)).parts
B : α
hB : B ∈ P.parts
hb : b ∈ (Q ↑{ val := B, property := hB } (_ : ↑{ val := B, property := hB } ∈ P.parts)).parts
hAB : A ≠ B
⊢ (Disjoint on id) a b

Next tactic:
exact (P.disjoint hA hB hAB).mono ((Q A hA).le ha) ((Q B hB).le hb)
/-- Given a finpartition `P` of `a` and finpartitions of each part of `P`, this yields the
finpartition of `a` obtained by juxtaposing all the subpartitions. -/
@[simps]
def bind (P : Finpartition a) (Q : ∀ i ∈ P.parts, Finpartition i) : Finpartition a
    where
  parts := P.parts.attach.biUnion fun i ↦ (Q i.1 i.2).parts
  supIndep := by
    rw [supIndep_iff_pairwiseDisjoint]
    rintro a ha b hb h
    rw [Finset.mem_coe, Finset.mem_biUnion] at ha hb
    obtain ⟨⟨A, hA⟩, -, ha⟩ := ha
    obtain ⟨⟨B, hB⟩, -, hb⟩ := hb
    obtain rfl | hAB := eq_or_ne A B
    · exact (Q A hA).disjoint ha hb h
    · exact (P.disjoint hA hB hAB).mono ((Q A hA).le ha) ((Q B hB).le hb)
  supParts := by
    

Proof state:
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b c : α
P✝ : Finpartition a
Q✝ : (i : α) → i ∈ P✝.parts → Finpartition i
P : Finpartition a
Q : (i : α) → i ∈ P.parts → Finpartition i
⊢ sup (Finset.biUnion (attach P.parts) fun i => (Q ↑i (_ : ↑i ∈ P.parts)).parts) id = a

Next tactic:
simp_rw [sup_biUnion]
/-- Given a finpartition `P` of `a` and finpartitions of each part of `P`, this yields the
finpartition of `a` obtained by juxtaposing all the subpartitions. -/
@[simps]
def bind (P : Finpartition a) (Q : ∀ i ∈ P.parts, Finpartition i) : Finpartition a
    where
  parts := P.parts.attach.biUnion fun i ↦ (Q i.1 i.2).parts
  supIndep := by
    rw [supIndep_iff_pairwiseDisjoint]
    rintro a ha b hb h
    rw [Finset.mem_coe, Finset.mem_biUnion] at ha hb
    obtain ⟨⟨A, hA⟩, -, ha⟩ := ha
    obtain ⟨⟨B, hB⟩, -, hb⟩ := hb
    obtain rfl | hAB := eq_or_ne A B
    · exact (Q A hA).disjoint ha hb h
    · exact (P.disjoint hA hB hAB).mono ((Q A hA).le ha) ((Q B hB).le hb)
  supParts := by
    simp_rw [sup_biUnion]
    

Proof state:
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b c : α
P✝ : Finpartition a
Q✝ : (i : α) → i ∈ P✝.parts → Finpartition i
P : Finpartition a
Q : (i : α) → i ∈ P.parts → Finpartition i
⊢ (sup (attach P.parts) fun x => sup (Q ↑x (_ : ↑x ∈ P.parts)).parts id) = a

Next tactic:
trans (sup P.parts id)
/-- Given a finpartition `P` of `a` and finpartitions of each part of `P`, this yields the
finpartition of `a` obtained by juxtaposing all the subpartitions. -/
@[simps]
def bind (P : Finpartition a) (Q : ∀ i ∈ P.parts, Finpartition i) : Finpartition a
    where
  parts := P.parts.attach.biUnion fun i ↦ (Q i.1 i.2).parts
  supIndep := by
    rw [supIndep_iff_pairwiseDisjoint]
    rintro a ha b hb h
    rw [Finset.mem_coe, Finset.mem_biUnion] at ha hb
    obtain ⟨⟨A, hA⟩, -, ha⟩ := ha
    obtain ⟨⟨B, hB⟩, -, hb⟩ := hb
    obtain rfl | hAB := eq_or_ne A B
    · exact (Q A hA).disjoint ha hb h
    · exact (P.disjoint hA hB hAB).mono ((Q A hA).le ha) ((Q B hB).le hb)
  supParts := by
    simp_rw [sup_biUnion]
    trans (sup P.parts id)
    · 

Proof state:
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b c : α
P✝ : Finpartition a
Q✝ : (i : α) → i ∈ P✝.parts → Finpartition i
P : Finpartition a
Q : (i : α) → i ∈ P.parts → Finpartition i
⊢ (sup (attach P.parts) fun x => sup (Q ↑x (_ : ↑x ∈ P.parts)).parts id) = sup P.parts id

Next tactic:
rw [eq_comm, ← Finset.sup_attach]
/-- Given a finpartition `P` of `a` and finpartitions of each part of `P`, this yields the
finpartition of `a` obtained by juxtaposing all the subpartitions. -/
@[simps]
def bind (P : Finpartition a) (Q : ∀ i ∈ P.parts, Finpartition i) : Finpartition a
    where
  parts := P.parts.attach.biUnion fun i ↦ (Q i.1 i.2).parts
  supIndep := by
    rw [supIndep_iff_pairwiseDisjoint]
    rintro a ha b hb h
    rw [Finset.mem_coe, Finset.mem_biUnion] at ha hb
    obtain ⟨⟨A, hA⟩, -, ha⟩ := ha
    obtain ⟨⟨B, hB⟩, -, hb⟩ := hb
    obtain rfl | hAB := eq_or_ne A B
    · exact (Q A hA).disjoint ha hb h
    · exact (P.disjoint hA hB hAB).mono ((Q A hA).le ha) ((Q B hB).le hb)
  supParts := by
    simp_rw [sup_biUnion]
    trans (sup P.parts id)
    · rw [eq_comm, ← Finset.sup_attach]
      

Proof state:
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b c : α
P✝ : Finpartition a
Q✝ : (i : α) → i ∈ P✝.parts → Finpartition i
P : Finpartition a
Q : (i : α) → i ∈ P.parts → Finpartition i
⊢ (sup (attach P.parts) fun x => id ↑x) = sup (attach P.parts) fun x => sup (Q ↑x (_ : ↑x ∈ P.parts)).parts id

Next tactic:
exact sup_congr rfl fun b _hb ↦ (Q b.1 b.2).supParts.symm
/-- Given a finpartition `P` of `a` and finpartitions of each part of `P`, this yields the
finpartition of `a` obtained by juxtaposing all the subpartitions. -/
@[simps]
def bind (P : Finpartition a) (Q : ∀ i ∈ P.parts, Finpartition i) : Finpartition a
    where
  parts := P.parts.attach.biUnion fun i ↦ (Q i.1 i.2).parts
  supIndep := by
    rw [supIndep_iff_pairwiseDisjoint]
    rintro a ha b hb h
    rw [Finset.mem_coe, Finset.mem_biUnion] at ha hb
    obtain ⟨⟨A, hA⟩, -, ha⟩ := ha
    obtain ⟨⟨B, hB⟩, -, hb⟩ := hb
    obtain rfl | hAB := eq_or_ne A B
    · exact (Q A hA).disjoint ha hb h
    · exact (P.disjoint hA hB hAB).mono ((Q A hA).le ha) ((Q B hB).le hb)
  supParts := by
    simp_rw [sup_biUnion]
    trans (sup P.parts id)
    · rw [eq_comm, ← Finset.sup_attach]
      exact sup_congr rfl fun b _hb ↦ (Q b.1 b.2).supParts.symm
    · 

Proof state:
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b c : α
P✝ : Finpartition a
Q✝ : (i : α) → i ∈ P✝.parts → Finpartition i
P : Finpartition a
Q : (i : α) → i ∈ P.parts → Finpartition i
⊢ sup P.parts id = a

Next tactic:
exact P.supParts
/-- Given a finpartition `P` of `a` and finpartitions of each part of `P`, this yields the
finpartition of `a` obtained by juxtaposing all the subpartitions. -/
@[simps]
def bind (P : Finpartition a) (Q : ∀ i ∈ P.parts, Finpartition i) : Finpartition a
    where
  parts := P.parts.attach.biUnion fun i ↦ (Q i.1 i.2).parts
  supIndep := by
    rw [supIndep_iff_pairwiseDisjoint]
    rintro a ha b hb h
    rw [Finset.mem_coe, Finset.mem_biUnion] at ha hb
    obtain ⟨⟨A, hA⟩, -, ha⟩ := ha
    obtain ⟨⟨B, hB⟩, -, hb⟩ := hb
    obtain rfl | hAB := eq_or_ne A B
    · exact (Q A hA).disjoint ha hb h
    · exact (P.disjoint hA hB hAB).mono ((Q A hA).le ha) ((Q B hB).le hb)
  supParts := by
    simp_rw [sup_biUnion]
    trans (sup P.parts id)
    · rw [eq_comm, ← Finset.sup_attach]
      exact sup_congr rfl fun b _hb ↦ (Q b.1 b.2).supParts.symm
    · exact P.supParts
  not_bot_mem h := by
    

Proof state:
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b c : α
P✝ : Finpartition a
Q✝ : (i : α) → i ∈ P✝.parts → Finpartition i
P : Finpartition a
Q : (i : α) → i ∈ P.parts → Finpartition i
h : ⊥ ∈ Finset.biUnion (attach P.parts) fun i => (Q ↑i (_ : ↑i ∈ P.parts)).parts
⊢ False

Next tactic:
rw [Finset.mem_biUnion] at h
/-- Given a finpartition `P` of `a` and finpartitions of each part of `P`, this yields the
finpartition of `a` obtained by juxtaposing all the subpartitions. -/
@[simps]
def bind (P : Finpartition a) (Q : ∀ i ∈ P.parts, Finpartition i) : Finpartition a
    where
  parts := P.parts.attach.biUnion fun i ↦ (Q i.1 i.2).parts
  supIndep := by
    rw [supIndep_iff_pairwiseDisjoint]
    rintro a ha b hb h
    rw [Finset.mem_coe, Finset.mem_biUnion] at ha hb
    obtain ⟨⟨A, hA⟩, -, ha⟩ := ha
    obtain ⟨⟨B, hB⟩, -, hb⟩ := hb
    obtain rfl | hAB := eq_or_ne A B
    · exact (Q A hA).disjoint ha hb h
    · exact (P.disjoint hA hB hAB).mono ((Q A hA).le ha) ((Q B hB).le hb)
  supParts := by
    simp_rw [sup_biUnion]
    trans (sup P.parts id)
    · rw [eq_comm, ← Finset.sup_attach]
      exact sup_congr rfl fun b _hb ↦ (Q b.1 b.2).supParts.symm
    · exact P.supParts
  not_bot_mem h := by
    rw [Finset.mem_biUnion] at h
    

Proof state:
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b c : α
P✝ : Finpartition a
Q✝ : (i : α) → i ∈ P✝.parts → Finpartition i
P : Finpartition a
Q : (i : α) → i ∈ P.parts → Finpartition i
h : ∃ a_1 ∈ attach P.parts, ⊥ ∈ (Q ↑a_1 (_ : ↑a_1 ∈ P.parts)).parts
⊢ False

Next tactic:
obtain ⟨⟨A, hA⟩, -, h⟩ := h
/-- Given a finpartition `P` of `a` and finpartitions of each part of `P`, this yields the
finpartition of `a` obtained by juxtaposing all the subpartitions. -/
@[simps]
def bind (P : Finpartition a) (Q : ∀ i ∈ P.parts, Finpartition i) : Finpartition a
    where
  parts := P.parts.attach.biUnion fun i ↦ (Q i.1 i.2).parts
  supIndep := by
    rw [supIndep_iff_pairwiseDisjoint]
    rintro a ha b hb h
    rw [Finset.mem_coe, Finset.mem_biUnion] at ha hb
    obtain ⟨⟨A, hA⟩, -, ha⟩ := ha
    obtain ⟨⟨B, hB⟩, -, hb⟩ := hb
    obtain rfl | hAB := eq_or_ne A B
    · exact (Q A hA).disjoint ha hb h
    · exact (P.disjoint hA hB hAB).mono ((Q A hA).le ha) ((Q B hB).le hb)
  supParts := by
    simp_rw [sup_biUnion]
    trans (sup P.parts id)
    · rw [eq_comm, ← Finset.sup_attach]
      exact sup_congr rfl fun b _hb ↦ (Q b.1 b.2).supParts.symm
    · exact P.supParts
  not_bot_mem h := by
    rw [Finset.mem_biUnion] at h
    obtain ⟨⟨A, hA⟩, -, h⟩ := h
    

Proof state:
case intro.mk.intro
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b c : α
P✝ : Finpartition a
Q✝ : (i : α) → i ∈ P✝.parts → Finpartition i
P : Finpartition a
Q : (i : α) → i ∈ P.parts → Finpartition i
A : α
hA : A ∈ P.parts
h : ⊥ ∈ (Q ↑{ val := A, property := hA } (_ : ↑{ val := A, property := hA } ∈ P.parts)).parts
⊢ False

Next tactic:
exact (Q A hA).not_bot_mem h
theorem mem_bind : b ∈ (P.bind Q).parts ↔ ∃ A hA, b ∈ (Q A hA).parts := by
  

Proof state:
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b c : α
P : Finpartition a
Q : (i : α) → i ∈ P.parts → Finpartition i
⊢ b ∈ (bind P Q).parts ↔ ∃ A, ∃ (hA : A ∈ P.parts), b ∈ (Q A hA).parts

Next tactic:
rw [bind, mem_biUnion]
theorem mem_bind : b ∈ (P.bind Q).parts ↔ ∃ A hA, b ∈ (Q A hA).parts := by
  rw [bind, mem_biUnion]
  

Proof state:
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b c : α
P : Finpartition a
Q : (i : α) → i ∈ P.parts → Finpartition i
⊢ (∃ a_1 ∈ attach P.parts, b ∈ (Q ↑a_1 (_ : ↑a_1 ∈ P.parts)).parts) ↔ ∃ A, ∃ (hA : A ∈ P.parts), b ∈ (Q A hA).parts

Next tactic:
constructor
theorem mem_bind : b ∈ (P.bind Q).parts ↔ ∃ A hA, b ∈ (Q A hA).parts := by
  rw [bind, mem_biUnion]
  constructor
  · 

Proof state:
case mp
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b c : α
P : Finpartition a
Q : (i : α) → i ∈ P.parts → Finpartition i
⊢ (∃ a_1 ∈ attach P.parts, b ∈ (Q ↑a_1 (_ : ↑a_1 ∈ P.parts)).parts) → ∃ A, ∃ (hA : A ∈ P.parts), b ∈ (Q A hA).parts

Next tactic:
rintro ⟨⟨A, hA⟩, -, h⟩
theorem mem_bind : b ∈ (P.bind Q).parts ↔ ∃ A hA, b ∈ (Q A hA).parts := by
  rw [bind, mem_biUnion]
  constructor
  · rintro ⟨⟨A, hA⟩, -, h⟩
    

Proof state:
case mp.intro.mk.intro
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b c : α
P : Finpartition a
Q : (i : α) → i ∈ P.parts → Finpartition i
A : α
hA : A ∈ P.parts
h : b ∈ (Q ↑{ val := A, property := hA } (_ : ↑{ val := A, property := hA } ∈ P.parts)).parts
⊢ ∃ A, ∃ (hA : A ∈ P.parts), b ∈ (Q A hA).parts

Next tactic:
exact ⟨A, hA, h⟩
theorem mem_bind : b ∈ (P.bind Q).parts ↔ ∃ A hA, b ∈ (Q A hA).parts := by
  rw [bind, mem_biUnion]
  constructor
  · rintro ⟨⟨A, hA⟩, -, h⟩
    exact ⟨A, hA, h⟩
  · 

Proof state:
case mpr
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b c : α
P : Finpartition a
Q : (i : α) → i ∈ P.parts → Finpartition i
⊢ (∃ A, ∃ (hA : A ∈ P.parts), b ∈ (Q A hA).parts) → ∃ a_2 ∈ attach P.parts, b ∈ (Q ↑a_2 (_ : ↑a_2 ∈ P.parts)).parts

Next tactic:
rintro ⟨A, hA, h⟩
theorem mem_bind : b ∈ (P.bind Q).parts ↔ ∃ A hA, b ∈ (Q A hA).parts := by
  rw [bind, mem_biUnion]
  constructor
  · rintro ⟨⟨A, hA⟩, -, h⟩
    exact ⟨A, hA, h⟩
  · rintro ⟨A, hA, h⟩
    

Proof state:
case mpr.intro.intro
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b c : α
P : Finpartition a
Q : (i : α) → i ∈ P.parts → Finpartition i
A : α
hA : A ∈ P.parts
h : b ∈ (Q A hA).parts
⊢ ∃ a_1 ∈ attach P.parts, b ∈ (Q ↑a_1 (_ : ↑a_1 ∈ P.parts)).parts

Next tactic:
exact ⟨⟨A, hA⟩, mem_attach _ ⟨A, hA⟩, h⟩
theorem card_bind (Q : ∀ i ∈ P.parts, Finpartition i) :
    (P.bind Q).parts.card = ∑ A in P.parts.attach, (Q _ A.2).parts.card := by
  

Proof state:
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b c : α
P : Finpartition a
Q✝ Q : (i : α) → i ∈ P.parts → Finpartition i
⊢ card (bind P Q).parts = ∑ A in attach P.parts, card (Q ↑A (_ : ↑A ∈ P.parts)).parts

Next tactic:
apply card_biUnion
theorem card_bind (Q : ∀ i ∈ P.parts, Finpartition i) :
    (P.bind Q).parts.card = ∑ A in P.parts.attach, (Q _ A.2).parts.card := by
  apply card_biUnion
  

Proof state:
case h
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b c : α
P : Finpartition a
Q✝ Q : (i : α) → i ∈ P.parts → Finpartition i
⊢ ∀ x ∈ attach P.parts,
    ∀ y ∈ attach P.parts,
      x ≠ y → Disjoint ((fun i => (Q ↑i (_ : ↑i ∈ P.parts)).parts) x) ((fun i => (Q ↑i (_ : ↑i ∈ P.parts)).parts) y)

Next tactic:
rintro ⟨b, hb⟩ - ⟨c, hc⟩ - hbc
theorem card_bind (Q : ∀ i ∈ P.parts, Finpartition i) :
    (P.bind Q).parts.card = ∑ A in P.parts.attach, (Q _ A.2).parts.card := by
  apply card_biUnion
  rintro ⟨b, hb⟩ - ⟨c, hc⟩ - hbc
  

Proof state:
case h.mk.mk
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b✝ c✝ : α
P : Finpartition a
Q✝ Q : (i : α) → i ∈ P.parts → Finpartition i
b : α
hb : b ∈ P.parts
c : α
hc : c ∈ P.parts
hbc : { val := b, property := hb } ≠ { val := c, property := hc }
⊢ Disjoint ((fun i => (Q ↑i (_ : ↑i ∈ P.parts)).parts) { val := b, property := hb })
    ((fun i => (Q ↑i (_ : ↑i ∈ P.parts)).parts) { val := c, property := hc })

Next tactic:
rw [Finset.disjoint_left]
theorem card_bind (Q : ∀ i ∈ P.parts, Finpartition i) :
    (P.bind Q).parts.card = ∑ A in P.parts.attach, (Q _ A.2).parts.card := by
  apply card_biUnion
  rintro ⟨b, hb⟩ - ⟨c, hc⟩ - hbc
  rw [Finset.disjoint_left]
  

Proof state:
case h.mk.mk
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b✝ c✝ : α
P : Finpartition a
Q✝ Q : (i : α) → i ∈ P.parts → Finpartition i
b : α
hb : b ∈ P.parts
c : α
hc : c ∈ P.parts
hbc : { val := b, property := hb } ≠ { val := c, property := hc }
⊢ ∀ ⦃a_1 : α⦄,
    a_1 ∈ (fun i => (Q ↑i (_ : ↑i ∈ P.parts)).parts) { val := b, property := hb } →
      a_1 ∉ (fun i => (Q ↑i (_ : ↑i ∈ P.parts)).parts) { val := c, property := hc }

Next tactic:
rintro d hdb hdc
theorem card_bind (Q : ∀ i ∈ P.parts, Finpartition i) :
    (P.bind Q).parts.card = ∑ A in P.parts.attach, (Q _ A.2).parts.card := by
  apply card_biUnion
  rintro ⟨b, hb⟩ - ⟨c, hc⟩ - hbc
  rw [Finset.disjoint_left]
  rintro d hdb hdc
  

Proof state:
case h.mk.mk
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b✝ c✝ : α
P : Finpartition a
Q✝ Q : (i : α) → i ∈ P.parts → Finpartition i
b : α
hb : b ∈ P.parts
c : α
hc : c ∈ P.parts
hbc : { val := b, property := hb } ≠ { val := c, property := hc }
d : α
hdb : d ∈ (fun i => (Q ↑i (_ : ↑i ∈ P.parts)).parts) { val := b, property := hb }
hdc : d ∈ (fun i => (Q ↑i (_ : ↑i ∈ P.parts)).parts) { val := c, property := hc }
⊢ False

Next tactic:
rw [Ne.def, Subtype.mk_eq_mk] at hbc
theorem card_bind (Q : ∀ i ∈ P.parts, Finpartition i) :
    (P.bind Q).parts.card = ∑ A in P.parts.attach, (Q _ A.2).parts.card := by
  apply card_biUnion
  rintro ⟨b, hb⟩ - ⟨c, hc⟩ - hbc
  rw [Finset.disjoint_left]
  rintro d hdb hdc
  rw [Ne.def, Subtype.mk_eq_mk] at hbc
  

Proof state:
case h.mk.mk
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b✝ c✝ : α
P : Finpartition a
Q✝ Q : (i : α) → i ∈ P.parts → Finpartition i
b : α
hb : b ∈ P.parts
c : α
hc : c ∈ P.parts
hbc : ¬b = c
d : α
hdb : d ∈ (fun i => (Q ↑i (_ : ↑i ∈ P.parts)).parts) { val := b, property := hb }
hdc : d ∈ (fun i => (Q ↑i (_ : ↑i ∈ P.parts)).parts) { val := c, property := hc }
⊢ False

Next tactic:
exact
    (Q b hb).ne_bot hdb
      (eq_bot_iff.2 <|
        (le_inf ((Q b hb).le hdb) <| (Q c hc).le hdc).trans <| (P.disjoint hb hc hbc).le_bot)
/-- Adds `b` to a finpartition of `a` to make a finpartition of `a ⊔ b`. -/
@[simps]
def extend (P : Finpartition a) (hb : b ≠ ⊥) (hab : Disjoint a b) (hc : a ⊔ b = c) : Finpartition c
    where
  parts := insert b P.parts
  supIndep := by
    

Proof state:
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b c : α
P : Finpartition a
hb : b ≠ ⊥
hab : Disjoint a b
hc : a ⊔ b = c
⊢ SupIndep (insert b P.parts) id

Next tactic:
rw [supIndep_iff_pairwiseDisjoint, coe_insert]
/-- Adds `b` to a finpartition of `a` to make a finpartition of `a ⊔ b`. -/
@[simps]
def extend (P : Finpartition a) (hb : b ≠ ⊥) (hab : Disjoint a b) (hc : a ⊔ b = c) : Finpartition c
    where
  parts := insert b P.parts
  supIndep := by
    rw [supIndep_iff_pairwiseDisjoint, coe_insert]
    

Proof state:
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b c : α
P : Finpartition a
hb : b ≠ ⊥
hab : Disjoint a b
hc : a ⊔ b = c
⊢ Set.PairwiseDisjoint (insert b ↑P.parts) id

Next tactic:
exact P.disjoint.insert fun d hd _ ↦ hab.symm.mono_right <| P.le hd
/-- Adds `b` to a finpartition of `a` to make a finpartition of `a ⊔ b`. -/
@[simps]
def extend (P : Finpartition a) (hb : b ≠ ⊥) (hab : Disjoint a b) (hc : a ⊔ b = c) : Finpartition c
    where
  parts := insert b P.parts
  supIndep := by
    rw [supIndep_iff_pairwiseDisjoint, coe_insert]
    exact P.disjoint.insert fun d hd _ ↦ hab.symm.mono_right <| P.le hd
  supParts := by 

Proof state:
α : Type u_1
inst✝² : DistribLattice α
inst✝¹ : OrderBot α
inst✝ : DecidableEq α
a b c : α
P : Finpartition a
hb : b ≠ ⊥
hab : Disjoint a b
hc : a ⊔ b = c
⊢ sup (insert b P.parts) id = c

Next tactic:
rwa [sup_insert, P.supParts, id, _root_.sup_comm]
/-- Restricts a finpartition to avoid a given element. -/
@[simps!]
def avoid (b : α) : Finpartition (a \ b) :=
  ofErase
    (P.parts.image (· \ b))
    (P.disjoint.image_finset_of_le fun a ↦ sdiff_le).supIndep
    (by 

Proof state:
α : Type u_1
inst✝¹ : GeneralizedBooleanAlgebra α
inst✝ : DecidableEq α
a b✝ c : α
P : Finpartition a
b : α
⊢ sup (image (fun x => x \ b) P.parts) id = a \ b

Next tactic:
rw [sup_image, comp.left_id, Finset.sup_sdiff_right, ← id_def, P.supParts]
@[simp]
theorem mem_avoid : c ∈ (P.avoid b).parts ↔ ∃ d ∈ P.parts, ¬d ≤ b ∧ d \ b = c := by
  

Proof state:
α : Type u_1
inst✝¹ : GeneralizedBooleanAlgebra α
inst✝ : DecidableEq α
a b c : α
P : Finpartition a
⊢ c ∈ (avoid P b).parts ↔ ∃ d ∈ P.parts, ¬d ≤ b ∧ d \ b = c

Next tactic:
simp only [avoid, ofErase, mem_erase, Ne.def, mem_image, exists_prop, ← exists_and_left,
    @and_left_comm (c ≠ ⊥)]
@[simp]
theorem mem_avoid : c ∈ (P.avoid b).parts ↔ ∃ d ∈ P.parts, ¬d ≤ b ∧ d \ b = c := by
  simp only [avoid, ofErase, mem_erase, Ne.def, mem_image, exists_prop, ← exists_and_left,
    @and_left_comm (c ≠ ⊥)]
  

Proof state:
α : Type u_1
inst✝¹ : GeneralizedBooleanAlgebra α
inst✝ : DecidableEq α
a b c : α
P : Finpartition a
⊢ (∃ x ∈ P.parts, ¬c = ⊥ ∧ x \ b = c) ↔ ∃ d ∈ P.parts, ¬d ≤ b ∧ d \ b = c

Next tactic:
refine' exists_congr fun d ↦ and_congr_right' <| and_congr_left _
@[simp]
theorem mem_avoid : c ∈ (P.avoid b).parts ↔ ∃ d ∈ P.parts, ¬d ≤ b ∧ d \ b = c := by
  simp only [avoid, ofErase, mem_erase, Ne.def, mem_image, exists_prop, ← exists_and_left,
    @and_left_comm (c ≠ ⊥)]
  refine' exists_congr fun d ↦ and_congr_right' <| and_congr_left _
  

Proof state:
α : Type u_1
inst✝¹ : GeneralizedBooleanAlgebra α
inst✝ : DecidableEq α
a b c : α
P : Finpartition a
d : α
⊢ d \ b = c → (¬c = ⊥ ↔ ¬d ≤ b)

Next tactic:
rintro rfl
@[simp]
theorem mem_avoid : c ∈ (P.avoid b).parts ↔ ∃ d ∈ P.parts, ¬d ≤ b ∧ d \ b = c := by
  simp only [avoid, ofErase, mem_erase, Ne.def, mem_image, exists_prop, ← exists_and_left,
    @and_left_comm (c ≠ ⊥)]
  refine' exists_congr fun d ↦ and_congr_right' <| and_congr_left _
  rintro rfl
  

Proof state:
α : Type u_1
inst✝¹ : GeneralizedBooleanAlgebra α
inst✝ : DecidableEq α
a b : α
P : Finpartition a
d : α
⊢ ¬d \ b = ⊥ ↔ ¬d ≤ b

Next tactic:
rw [sdiff_eq_bot_iff]
theorem exists_mem {a : α} (ha : a ∈ s) : ∃ t ∈ P.parts, a ∈ t := by
  

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s t u : Finset α
P : Finpartition s
a✝ a : α
ha : a ∈ s
⊢ ∃ t ∈ P.parts, a ∈ t

Next tactic:
simp_rw [← P.supParts] at ha
theorem exists_mem {a : α} (ha : a ∈ s) : ∃ t ∈ P.parts, a ∈ t := by
  simp_rw [← P.supParts] at ha
  

Proof state:
α : Type u_1
inst✝ : DecidableEq α
s t u : Finset α
P : Finpartition s
a✝ a : α
ha : a ∈ sup P.parts id
⊢ ∃ t ∈ P.parts, a ∈ t

Next tactic:
exact mem_sup.1 ha