-- Mathlib/NumberTheory/Dioph.lean
theorem union : ∀ (_ : Dioph S) (_ : Dioph S'), Dioph (S ∪ S')
  | ⟨β, p, pe⟩, ⟨γ, q, qe⟩ =>
    ⟨β ⊕ γ, p.map (inl ⊗ inr ∘ inl) * q.map (inl ⊗ inr ∘ inr), fun v => by
      refine
        Iff.trans (or_congr ((pe v).trans ?_) ((qe v).trans ?_))
          (exists_or.symm.trans
            (exists_congr fun t =>
              (@mul_eq_zero _ _ _ (p ((v ⊗ t) ∘ (inl ⊗ inr ∘ inl)))
                  (q ((v ⊗ t) ∘ (inl ⊗ inr ∘ inr)))).symm))
      -- Porting note: putting everything on the same line fails
      · refine inject_dummies_lem _ ?_ ?_ _ _
        · exact some ⊗ fun _ => none
        · exact fun _ => by simp only [elim_inl]
      -- Porting note: putting everything on the same line fails
      · refine inject_dummies_lem _ ?_ ?_ _ _
        · exact (fun _ => none) ⊗ some
        · exact fun _ => by simp only [elim_inr]⟩

Proof state:
α : Type u
S S' : Set (α → ℕ)
β : Type u
p : Poly (α ⊕ β)
pe : ∀ (v : α → ℕ), S v ↔ ∃ t, p (v ⊗ t) = 0
γ : Type u
q : Poly (α ⊕ γ)
qe : ∀ (v : α → ℕ), S' v ↔ ∃ t, q (v ⊗ t) = 0
v : α → ℕ
x✝ : β
⊢ (some ⊗ fun x => none) (inl x✝) = some x✝

Tactic:
simp only [elim_inl]

Result:
no goals

Proof state:
α : Type u
S S' : Set (α → ℕ)
β : Type u
p : Poly (α ⊕ β)
pe : ∀ (v : α → ℕ), S v ↔ ∃ t, p (v ⊗ t) = 0
γ : Type u
q : Poly (α ⊕ γ)
qe : ∀ (v : α → ℕ), S' v ↔ ∃ t, q (v ⊗ t) = 0
v : α → ℕ
⊢ (S ∪ S') v ↔ ∃ t, (Poly.map (inl ⊗ inr ∘ inl) p * Poly.map (inl ⊗ inr ∘ inr) q) (v ⊗ t) = 0

Tactic:
refine
  Iff.trans (or_congr ((pe v).trans ?_) ((qe v).trans ?_))
    (exists_or.symm.trans
      (exists_congr fun t =>
        (@mul_eq_zero _ _ _ (p ((v ⊗ t) ∘ (inl ⊗ inr ∘ inl)))
            (q ((v ⊗ t) ∘ (inl ⊗ inr ∘ inr)))).symm))

Result:
case refine_1
α : Type u
S S' : Set (α → ℕ)
β : Type u
p : Poly (α ⊕ β)
pe : ∀ (v : α → ℕ), S v ↔ ∃ t, p (v ⊗ t) = 0
γ : Type u
q : Poly (α ⊕ γ)
qe : ∀ (v : α → ℕ), S' v ↔ ∃ t, q (v ⊗ t) = 0
v : α → ℕ
⊢ (∃ t, p (v ⊗ t) = 0) ↔ ∃ x, p ((v ⊗ x) ∘ (inl ⊗ inr ∘ inl)) = 0

case refine_2
α : Type u
S S' : Set (α → ℕ)
β : Type u
p : Poly (α ⊕ β)
pe : ∀ (v : α → ℕ), S v ↔ ∃ t, p (v ⊗ t) = 0
γ : Type u
q : Poly (α ⊕ γ)
qe : ∀ (v : α → ℕ), S' v ↔ ∃ t, q (v ⊗ t) = 0
v : α → ℕ
⊢ (∃ t, q (v ⊗ t) = 0) ↔ ∃ x, q ((v ⊗ x) ∘ (inl ⊗ inr ∘ inr)) = 0

Proof state:
case refine_1.refine_1
α : Type u
S S' : Set (α → ℕ)
β : Type u
p : Poly (α ⊕ β)
pe : ∀ (v : α → ℕ), S v ↔ ∃ t, p (v ⊗ t) = 0
γ : Type u
q : Poly (α ⊕ γ)
qe : ∀ (v : α → ℕ), S' v ↔ ∃ t, q (v ⊗ t) = 0
v : α → ℕ
⊢ β ⊕ γ → Option β

Tactic:
exact some ⊗ fun _ => none

Result:
no goals

Proof state:
α : Type u
S S' : Set (α → ℕ)
β : Type u
p : Poly (α ⊕ β)
pe : ∀ (v : α → ℕ), S v ↔ ∃ t, p (v ⊗ t) = 0
γ : Type u
q : Poly (α ⊕ γ)
qe : ∀ (v : α → ℕ), S' v ↔ ∃ t, q (v ⊗ t) = 0
v : α → ℕ
x✝ : γ
⊢ ((fun x => none) ⊗ some) (inr x✝) = some x✝

Tactic:
simp only [elim_inr]

Result:
no goals

Proof state:
case refine_2.refine_2
α : Type u
S S' : Set (α → ℕ)
β : Type u
p : Poly (α ⊕ β)
pe : ∀ (v : α → ℕ), S v ↔ ∃ t, p (v ⊗ t) = 0
γ : Type u
q : Poly (α ⊕ γ)
qe : ∀ (v : α → ℕ), S' v ↔ ∃ t, q (v ⊗ t) = 0
v : α → ℕ
⊢ ∀ (x : γ), ((fun x => none) ⊗ some) (inr x) = some x

Tactic:
exact fun _ => by simp only [elim_inr]

Result:
no goals

Proof state:
case refine_2
α : Type u
S S' : Set (α → ℕ)
β : Type u
p : Poly (α ⊕ β)
pe : ∀ (v : α → ℕ), S v ↔ ∃ t, p (v ⊗ t) = 0
γ : Type u
q : Poly (α ⊕ γ)
qe : ∀ (v : α → ℕ), S' v ↔ ∃ t, q (v ⊗ t) = 0
v : α → ℕ
⊢ (∃ t, q (v ⊗ t) = 0) ↔ ∃ x, q ((v ⊗ x) ∘ (inl ⊗ inr ∘ inr)) = 0

Tactic:
refine inject_dummies_lem _ ?_ ?_ _ _

Result:
case refine_2.refine_1
α : Type u
S S' : Set (α → ℕ)
β : Type u
p : Poly (α ⊕ β)
pe : ∀ (v : α → ℕ), S v ↔ ∃ t, p (v ⊗ t) = 0
γ : Type u
q : Poly (α ⊕ γ)
qe : ∀ (v : α → ℕ), S' v ↔ ∃ t, q (v ⊗ t) = 0
v : α → ℕ
⊢ β ⊕ γ → Option γ

case refine_2.refine_2
α : Type u
S S' : Set (α → ℕ)
β : Type u
p : Poly (α ⊕ β)
pe : ∀ (v : α → ℕ), S v ↔ ∃ t, p (v ⊗ t) = 0
γ : Type u
q : Poly (α ⊕ γ)
qe : ∀ (v : α → ℕ), S' v ↔ ∃ t, q (v ⊗ t) = 0
v : α → ℕ
⊢ ∀ (x : γ), ?refine_2.refine_1 (inr x) = some x

Proof state:
case refine_1
α : Type u
S S' : Set (α → ℕ)
β : Type u
p : Poly (α ⊕ β)
pe : ∀ (v : α → ℕ), S v ↔ ∃ t, p (v ⊗ t) = 0
γ : Type u
q : Poly (α ⊕ γ)
qe : ∀ (v : α → ℕ), S' v ↔ ∃ t, q (v ⊗ t) = 0
v : α → ℕ
⊢ (∃ t, p (v ⊗ t) = 0) ↔ ∃ x, p ((v ⊗ x) ∘ (inl ⊗ inr ∘ inl)) = 0

Tactic:
refine inject_dummies_lem _ ?_ ?_ _ _

Result:
case refine_1.refine_1
α : Type u
S S' : Set (α → ℕ)
β : Type u
p : Poly (α ⊕ β)
pe : ∀ (v : α → ℕ), S v ↔ ∃ t, p (v ⊗ t) = 0
γ : Type u
q : Poly (α ⊕ γ)
qe : ∀ (v : α → ℕ), S' v ↔ ∃ t, q (v ⊗ t) = 0
v : α → ℕ
⊢ β ⊕ γ → Option β

case refine_1.refine_2
α : Type u
S S' : Set (α → ℕ)
β : Type u
p : Poly (α ⊕ β)
pe : ∀ (v : α → ℕ), S v ↔ ∃ t, p (v ⊗ t) = 0
γ : Type u
q : Poly (α ⊕ γ)
qe : ∀ (v : α → ℕ), S' v ↔ ∃ t, q (v ⊗ t) = 0
v : α → ℕ
⊢ ∀ (x : β), ?refine_1.refine_1 (inl x) = some x

Proof state:
case refine_1.refine_2
α : Type u
S S' : Set (α → ℕ)
β : Type u
p : Poly (α ⊕ β)
pe : ∀ (v : α → ℕ), S v ↔ ∃ t, p (v ⊗ t) = 0
γ : Type u
q : Poly (α ⊕ γ)
qe : ∀ (v : α → ℕ), S' v ↔ ∃ t, q (v ⊗ t) = 0
v : α → ℕ
⊢ ∀ (x : β), (some ⊗ fun x => none) (inl x) = some x

Tactic:
exact fun _ => by simp only [elim_inl]

Result:
no goals

Proof state:
case refine_2.refine_1
α : Type u
S S' : Set (α → ℕ)
β : Type u
p : Poly (α ⊕ β)
pe : ∀ (v : α → ℕ), S v ↔ ∃ t, p (v ⊗ t) = 0
γ : Type u
q : Poly (α ⊕ γ)
qe : ∀ (v : α → ℕ), S' v ↔ ∃ t, q (v ⊗ t) = 0
v : α → ℕ
⊢ β ⊕ γ → Option γ

Tactic:
exact (fun _ => none) ⊗ some

Result:
no goals