Theorem: Finset.filter_product_card
File: Mathlib/Data/Finset/Prod.lean

tactic: rw [← card_product, ← card_product, ← filter_product, ← filter_product, ← card_union_of_disjoint]
state_before: α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s' : Finset α
t✝ t' : Finset β
a : α
b : β
s : Finset α
t : Finset β
p : α → Prop
q : β → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
⊢ (filter (fun x => p x.1 = q x.2) (s ×ˢ t)).card =
    (filter p s).card * (filter q t).card + (filter (fun x => ¬p x) s).card * (filter (fun x => ¬q x) t).card
state_after: α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s' : Finset α
t✝ t' : Finset β
a : α
b : β
s : Finset α
t : Finset β
p : α → Prop
q : β → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
⊢ (filter (fun x => p x.1 = q x.2) (s ×ˢ t)).card =
    (filter (fun x => p x.1 ∧ q x.2) (s ×ˢ t) ∪ filter (fun x => ¬p x.1 ∧ ¬q x.2) (s ×ˢ t)).card

α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s' : Finset α
t✝ t' : Finset β
a : α
b : β
s : Finset α
t : Finset β
p : α → Prop
q : β → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
⊢ _root_.Disjoint (filter (fun x => p x.1 ∧ q x.2) (s ×ˢ t)) (filter (fun x => ¬p x.1 ∧ ¬q x.2) (s ×ˢ t))

tactic: apply congr_arg
state_before: α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s' : Finset α
t✝ t' : Finset β
a : α
b : β
s : Finset α
t : Finset β
p : α → Prop
q : β → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
⊢ (filter (fun x => p x.1 = q x.2) (s ×ˢ t)).card =
    (filter (fun x => p x.1 ∧ q x.2) (s ×ˢ t) ∪ filter (fun x => ¬p x.1 ∧ ¬q x.2) (s ×ˢ t)).card
state_after: case h
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s' : Finset α
t✝ t' : Finset β
a : α
b : β
s : Finset α
t : Finset β
p : α → Prop
q : β → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
⊢ filter (fun x => p x.1 = q x.2) (s ×ˢ t) =
    filter (fun x => p x.1 ∧ q x.2) (s ×ˢ t) ∪ filter (fun x => ¬p x.1 ∧ ¬q x.2) (s ×ˢ t)

tactic: ext ⟨a, b⟩
state_before: case h
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s' : Finset α
t✝ t' : Finset β
a : α
b : β
s : Finset α
t : Finset β
p : α → Prop
q : β → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
⊢ filter (fun x => p x.1 = q x.2) (s ×ˢ t) =
    filter (fun x => p x.1 ∧ q x.2) (s ×ˢ t) ∪ filter (fun x => ¬p x.1 ∧ ¬q x.2) (s ×ˢ t)
state_after: case h.a.mk
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s' : Finset α
t✝ t' : Finset β
a✝ : α
b✝ : β
s : Finset α
t : Finset β
p : α → Prop
q : β → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
a : α
b : β
⊢ (a, b) ∈ filter (fun x => p x.1 = q x.2) (s ×ˢ t) ↔
    (a, b) ∈ filter (fun x => p x.1 ∧ q x.2) (s ×ˢ t) ∪ filter (fun x => ¬p x.1 ∧ ¬q x.2) (s ×ˢ t)

tactic: simp only [filter_union_right, mem_filter, mem_product]
state_before: case h.a.mk
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s' : Finset α
t✝ t' : Finset β
a✝ : α
b✝ : β
s : Finset α
t : Finset β
p : α → Prop
q : β → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
a : α
b : β
⊢ (a, b) ∈ filter (fun x => p x.1 = q x.2) (s ×ˢ t) ↔
    (a, b) ∈ filter (fun x => p x.1 ∧ q x.2) (s ×ˢ t) ∪ filter (fun x => ¬p x.1 ∧ ¬q x.2) (s ×ˢ t)
state_after: case h.a.mk
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s' : Finset α
t✝ t' : Finset β
a✝ : α
b✝ : β
s : Finset α
t : Finset β
p : α → Prop
q : β → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
a : α
b : β
⊢ (a ∈ s ∧ b ∈ t) ∧ p a = q b ↔ (a ∈ s ∧ b ∈ t) ∧ (p a ∧ q b ∨ ¬p a ∧ ¬q b)

tactic: constructor <;> intro h <;> use h.1
state_before: case h.a.mk
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s' : Finset α
t✝ t' : Finset β
a✝ : α
b✝ : β
s : Finset α
t : Finset β
p : α → Prop
q : β → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
a : α
b : β
⊢ (a ∈ s ∧ b ∈ t) ∧ p a = q b ↔ (a ∈ s ∧ b ∈ t) ∧ (p a ∧ q b ∨ ¬p a ∧ ¬q b)
state_after: case right
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s' : Finset α
t✝ t' : Finset β
a✝ : α
b✝ : β
s : Finset α
t : Finset β
p : α → Prop
q : β → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
a : α
b : β
h : (a ∈ s ∧ b ∈ t) ∧ p a = q b
⊢ p a ∧ q b ∨ ¬p a ∧ ¬q b

case right
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s' : Finset α
t✝ t' : Finset β
a✝ : α
b✝ : β
s : Finset α
t : Finset β
p : α → Prop
q : β → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
a : α
b : β
h : (a ∈ s ∧ b ∈ t) ∧ (p a ∧ q b ∨ ¬p a ∧ ¬q b)
⊢ p a = q b

tactic: simp only [h.2, Function.comp_apply, Decidable.em, and_self]
state_before: case right
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s' : Finset α
t✝ t' : Finset β
a✝ : α
b✝ : β
s : Finset α
t : Finset β
p : α → Prop
q : β → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
a : α
b : β
h : (a ∈ s ∧ b ∈ t) ∧ p a = q b
⊢ p a ∧ q b ∨ ¬p a ∧ ¬q b
state_after: no goals

tactic: revert h
state_before: case right
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s' : Finset α
t✝ t' : Finset β
a✝ : α
b✝ : β
s : Finset α
t : Finset β
p : α → Prop
q : β → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
a : α
b : β
h : (a ∈ s ∧ b ∈ t) ∧ (p a ∧ q b ∨ ¬p a ∧ ¬q b)
⊢ p a = q b
state_after: case right
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s' : Finset α
t✝ t' : Finset β
a✝ : α
b✝ : β
s : Finset α
t : Finset β
p : α → Prop
q : β → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
a : α
b : β
⊢ (a ∈ s ∧ b ∈ t) ∧ (p a ∧ q b ∨ ¬p a ∧ ¬q b) → p a = q b

tactic: simp only [Function.comp_apply, and_imp]
state_before: case right
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s' : Finset α
t✝ t' : Finset β
a✝ : α
b✝ : β
s : Finset α
t : Finset β
p : α → Prop
q : β → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
a : α
b : β
⊢ (a ∈ s ∧ b ∈ t) ∧ (p a ∧ q b ∨ ¬p a ∧ ¬q b) → p a = q b
state_after: case right
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s' : Finset α
t✝ t' : Finset β
a✝ : α
b✝ : β
s : Finset α
t : Finset β
p : α → Prop
q : β → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
a : α
b : β
⊢ a ∈ s → b ∈ t → p a ∧ q b ∨ ¬p a ∧ ¬q b → p a = q b

tactic: rintro _ _ (_|_) <;> simp [*]
state_before: case right
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s' : Finset α
t✝ t' : Finset β
a✝ : α
b✝ : β
s : Finset α
t : Finset β
p : α → Prop
q : β → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
a : α
b : β
⊢ a ∈ s → b ∈ t → p a ∧ q b ∨ ¬p a ∧ ¬q b → p a = q b
state_after: no goals

tactic: apply Finset.disjoint_filter_filter'
state_before: α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s' : Finset α
t✝ t' : Finset β
a : α
b : β
s : Finset α
t : Finset β
p : α → Prop
q : β → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
⊢ _root_.Disjoint (filter (fun x => p x.1 ∧ q x.2) (s ×ˢ t)) (filter (fun x => ¬p x.1 ∧ ¬q x.2) (s ×ˢ t))
state_after: case h
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s' : Finset α
t✝ t' : Finset β
a : α
b : β
s : Finset α
t : Finset β
p : α → Prop
q : β → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
⊢ _root_.Disjoint (fun x => p x.1 ∧ q x.2) fun x => ¬p x.1 ∧ ¬q x.2

tactic: exact (disjoint_compl_right.inf_left _).inf_right _
state_before: case h
α : Type u_1
β : Type u_2
γ : Type u_3
s✝ s' : Finset α
t✝ t' : Finset β
a : α
b : β
s : Finset α
t : Finset β
p : α → Prop
q : β → Prop
inst✝¹ : DecidablePred p
inst✝ : DecidablePred q
⊢ _root_.Disjoint (fun x => p x.1 ∧ q x.2) fun x => ¬p x.1 ∧ ¬q x.2
state_after: no goals