-- Mathlib/Order/Filter/Pointwise.lean
theorem mul_eq_one_iff : f * g = 1 ↔ ∃ a b, f = pure a ∧ g = pure b ∧ a * b = 1

Proof state:
case refine_1
α : Type u_2
inst✝ : DivisionMonoid α
f g : Filter α
hfg : f * g = 1
⊢ ∃ a b, f = pure a ∧ g = pure b ∧ a * b = 1

Tactic:
obtain ⟨t₁, h₁, t₂, h₂, h⟩ : (1 : Set α) ∈ f * g := hfg.symm ▸ one_mem_one

Result:
case refine_1.intro.intro.intro.intro
α : Type u_2
inst✝ : DivisionMonoid α
f g : Filter α
hfg : f * g = 1
t₁ : Set α
h₁ : t₁ ∈ f
t₂ : Set α
h₂ : t₂ ∈ g
h : t₁ * t₂ ⊆ 1
⊢ ∃ a b, f = pure a ∧ g = pure b ∧ a * b = 1

Proof state:
case refine_1.intro.intro.intro.intro.intro.intro.intro.intro.refine_2
α : Type u_2
inst✝ : DivisionMonoid α
f g : Filter α
hfg✝ : f * g = 1
hfg : (f * g).NeBot
a b : α
h₁ : {a} ∈ f
h : a * b = 1
h₂ : {b} ∈ g
⊢ g = pure b

Tactic:
rwa [← hfg.of_mul_right.le_pure_iff, le_pure_iff]

Result:
no goals

Proof state:
case refine_2.intro.intro.intro.intro
α : Type u_2
inst✝ : DivisionMonoid α
a b : α
h : a * b = 1
⊢ pure a * pure b = 1

Tactic:
rw [pure_mul_pure, h, pure_one]

Result:
no goals

Proof state:
α : Type u_2
inst✝ : DivisionMonoid α
f g : Filter α
⊢ f * g = 1 ↔ ∃ a b, f = pure a ∧ g = pure b ∧ a * b = 1

Tactic:
refine ⟨fun hfg => ?_, ?_⟩

Result:
case refine_1
α : Type u_2
inst✝ : DivisionMonoid α
f g : Filter α
hfg : f * g = 1
⊢ ∃ a b, f = pure a ∧ g = pure b ∧ a * b = 1

case refine_2
α : Type u_2
inst✝ : DivisionMonoid α
f g : Filter α
⊢ (∃ a b, f = pure a ∧ g = pure b ∧ a * b = 1) → f * g = 1

Proof state:
case refine_1.intro.intro.intro.intro.intro.intro.intro.intro
α : Type u_2
inst✝ : DivisionMonoid α
f g : Filter α
hfg✝ : f * g = 1
hfg : (f * g).NeBot
a b : α
h₁ : {a} ∈ f
h : a * b = 1
h₂ : {b} ∈ g
⊢ ∃ a b, f = pure a ∧ g = pure b ∧ a * b = 1

Tactic:
refine ⟨a, b, ?_, ?_, h⟩

Result:
case refine_1.intro.intro.intro.intro.intro.intro.intro.intro.refine_1
α : Type u_2
inst✝ : DivisionMonoid α
f g : Filter α
hfg✝ : f * g = 1
hfg : (f * g).NeBot
a b : α
h₁ : {a} ∈ f
h : a * b = 1
h₂ : {b} ∈ g
⊢ f = pure a

case refine_1.intro.intro.intro.intro.intro.intro.intro.intro.refine_2
α : Type u_2
inst✝ : DivisionMonoid α
f g : Filter α
hfg✝ : f * g = 1
hfg : (f * g).NeBot
a b : α
h₁ : {a} ∈ f
h : a * b = 1
h₂ : {b} ∈ g
⊢ g = pure b

Proof state:
case refine_1.intro.intro.intro.intro.intro.intro.intro.intro.refine_1
α : Type u_2
inst✝ : DivisionMonoid α
f g : Filter α
hfg✝ : f * g = 1
hfg : (f * g).NeBot
a b : α
h₁ : {a} ∈ f
h : a * b = 1
h₂ : {b} ∈ g
⊢ f = pure a

Tactic:
rwa [← hfg.of_mul_left.le_pure_iff, le_pure_iff]

Result:
no goals

Proof state:
case refine_1.intro.intro.intro.intro
α : Type u_2
inst✝ : DivisionMonoid α
f g : Filter α
hfg✝ : f * g = 1
t₁ : Set α
h₁ : t₁ ∈ f
t₂ : Set α
h₂ : t₂ ∈ g
h : t₁ * t₂ ⊆ 1
hfg : (f * g).NeBot
⊢ ∃ a b, f = pure a ∧ g = pure b ∧ a * b = 1

Tactic:
rw [(hfg.nonempty_of_mem <| mul_mem_mul h₁ h₂).subset_one_iff, Set.mul_eq_one_iff] at h

Result:
case refine_1.intro.intro.intro.intro
α : Type u_2
inst✝ : DivisionMonoid α
f g : Filter α
hfg✝ : f * g = 1
t₁ : Set α
h₁ : t₁ ∈ f
t₂ : Set α
h₂ : t₂ ∈ g
h : ∃ a b, t₁ = {a} ∧ t₂ = {b} ∧ a * b = 1
hfg : (f * g).NeBot
⊢ ∃ a b, f = pure a ∧ g = pure b ∧ a * b = 1

Proof state:
case refine_1.intro.intro.intro.intro
α : Type u_2
inst✝ : DivisionMonoid α
f g : Filter α
hfg✝ : f * g = 1
t₁ : Set α
h₁ : t₁ ∈ f
t₂ : Set α
h₂ : t₂ ∈ g
h : ∃ a b, t₁ = {a} ∧ t₂ = {b} ∧ a * b = 1
hfg : (f * g).NeBot
⊢ ∃ a b, f = pure a ∧ g = pure b ∧ a * b = 1

Tactic:
obtain ⟨a, b, rfl, rfl, h⟩ := h

Result:
case refine_1.intro.intro.intro.intro.intro.intro.intro.intro
α : Type u_2
inst✝ : DivisionMonoid α
f g : Filter α
hfg✝ : f * g = 1
hfg : (f * g).NeBot
a b : α
h₁ : {a} ∈ f
h : a * b = 1
h₂ : {b} ∈ g
⊢ ∃ a b, f = pure a ∧ g = pure b ∧ a * b = 1

Proof state:
case refine_2
α : Type u_2
inst✝ : DivisionMonoid α
f g : Filter α
⊢ (∃ a b, f = pure a ∧ g = pure b ∧ a * b = 1) → f * g = 1

Tactic:
rintro ⟨a, b, rfl, rfl, h⟩

Result:
case refine_2.intro.intro.intro.intro
α : Type u_2
inst✝ : DivisionMonoid α
a b : α
h : a * b = 1
⊢ pure a * pure b = 1

Proof state:
case refine_1.intro.intro.intro.intro
α : Type u_2
inst✝ : DivisionMonoid α
f g : Filter α
hfg : f * g = 1
t₁ : Set α
h₁ : t₁ ∈ f
t₂ : Set α
h₂ : t₂ ∈ g
h : t₁ * t₂ ⊆ 1
⊢ ∃ a b, f = pure a ∧ g = pure b ∧ a * b = 1

Tactic:
have hfg : (f * g).NeBot := hfg.symm.subst one_neBot

Result:
case refine_1.intro.intro.intro.intro
α : Type u_2
inst✝ : DivisionMonoid α
f g : Filter α
hfg✝ : f * g = 1
t₁ : Set α
h₁ : t₁ ∈ f
t₂ : Set α
h₂ : t₂ ∈ g
h : t₁ * t₂ ⊆ 1
hfg : (f * g).NeBot
⊢ ∃ a b, f = pure a ∧ g = pure b ∧ a * b = 1