4. Combining tactics

In this last section we cover examples involving division. The key tactic here is called field_simp: it clears denominators of fractions, which gets us back to a setting in which ring or polyrith can be applied.

4.1. Basics of the field_simp tactic

Given a ring expression with division or inversion, the field_simp tactic will clear any denominators for which it can determine that that denominator is nonzero.

Here is an example: we prove that if \(a\) and \(b\) are rational numbers, with \(a\) nonzero, then \(b = a ^ 2 + 3 a\) implies \(\tfrac{b}{a} - a = 3\). Check that if you delete the hypothesis that \(a \ne 0\) then field_simp fails to do anything useful.

example (a b : ) (ha : a  0) (H : b = a ^ 2 + 3 * a) : b / a - a = 3 := by
  field_simp
  linear_combination H

In the following problem we prove that the unit circle admits a rational parametrization:

\[\left(\frac{t ^ 2 - 1} {t ^ 2 + 1}\right) ^ 2 + \left(\frac{2 t } {t ^ 2 + 1}\right) ^ 2 = 1.\]

In this problem, the denominator, \(t ^ 2 + 1\), is “obviously positive”: it is the sum of a square and a strictly positive number. In such a situation field_simp will find the nonzeroness of the denominator automatically without us providing it.

example (t : ) : ((t ^ 2 - 1) / (t ^ 2 + 1)) ^ 2 + (2 * t  / (t ^ 2 + 1)) ^ 2 = 1 := by
  field_simp
  ring

Let’s tweak that problem to make it a bit harder. Suppose we want to prove the identity

\[\left(\frac{m ^ 2 - n ^ 2} {m ^ 2 + n ^ 2}\right) ^ 2 + \left(\frac{2 m n} {m ^ 2 + n ^ 2}\right) ^ 2 = 1,\]

which is valid whenever \((m,n)\ne (0,0)\). In this problem, field_simp cannot automatically prove the nonzeroness of the denominator, \(m ^ 2 + n ^ 2\). We need to provide a proof of the nonzeroness explicitly. Notice the use of contraposition and of (n)linarith in proving the nonzeroness hypothesis; these are both common ingredients. Again, check that if you comment out the justification that \(m ^ 2 + n ^ 2 \ne 0\), then field_simp fails to trigger.

example (m n : ) (hmn : (m, n)  0) :
    ((m ^ 2 - n ^ 2) / (m ^ 2 + n ^ 2)) ^ 2 + (2 * m * n / (m ^ 2 + n ^ 2)) ^ 2 = 1 := by
  have : m ^ 2 + n ^ 2  0 := by
    contrapose! hmn
    ext <;> dsimp <;> nlinarith
  field_simp
  ring

In the following problem we prove that if \(x\) is a primitive fifth root of unity, then \(x+1/x\) satisfies the quadratic equation

\[(x + 1/x) ^ 2 + (x + 1/x) - 1 = 0.\]

Here the denominator nonzeroness for field_simp is established by a contradiction argument: if \(x^5=0\) and \(x=0\) then polyrith can produce a numeric contradiction. Notice also that the nonzeroness hypothesis \(x\ne 1\) turns up later, when we follow the technique from Section 3.1.

Click through each invocation of polyrith to see what it gives you.

example {x : } (hx : x ^ 5 = 1) (hx' : x  1) : (x + 1 / x) ^ 2 + (x + 1 / x) - 1 = 0 := by
  have : x  0 := by
    intro h₀
    have : (1 : ) = 0 := by polyrith
    norm_num at this
  field_simp
  rw [ sub_ne_zero] at hx'
  apply mul_left_cancel₀ hx'
  polyrith

Here is an exercise. Let \(f:\mathbb{R}\to \mathbb{R}\) be the function

\[f(x)=\frac{1}{1-x}.\]

Away from the bad inputs \(x=0,1\), show that the triple composition of this function is the identity.

noncomputable def f :    := fun x => (1 - x)⁻¹

example {x : } (h₁ : x  1) (h₀ : x  0) : f (f (f x)) = x := by
  dsimp [f]
  sorry

4.2. Stereographic projection

In this section we construct stereographic projection as a bijection between the unit circle (minus its north pole) and the real line. The formulas for both directions of the bijection are fractions, so we will use field_simp repeatedly.

We introduce the notation 𝕊 for the unit circle in × , defined as the subtype of points \((x,y)\) such that \(x^2+y^2=1\).

The forward direction of the bijection is the map

\[(x,y) \mapsto \frac{2x}{1-y}.\]
/-- Stereographic projection, forward direction. This is a map from `ℝ × ℝ` to `ℝ`. It is
smooth away from the horizontal line `v.2 = 1`.  It restricts on the unit circle to the
stereographic projection. -/
def stereoToFun (p : 𝕊) :  := 2 * p.val.1 / (1 - p.val.2)

The backward direction of the bijection is the map

\[w \mapsto \frac{1}{w^2+4}\left(4w, w ^ 2 - 4\right).\]

Here we encounter our first proof obligation. We want to prove this is well-defined as a map from \(\mathbb{R}\) to the circle, so we must prove that the norm-square of this expression is 1. Fill in the proof below, using field_simp. In this case there is no need to justify that the denominator, \(w^2+4\), is nonzero: it is clearly strictly positive, so field_simp finds the nonzeroness automatically.

/-- Stereographic projection, reverse direction.  This is a map from `ℝ` to the unit circle
`𝕊` in `ℝ × ℝ`. -/
def stereoInvFun (w : ) : 𝕊 where
  val := (w ^ 2 + 4)⁻¹  (4 * w, w ^ 2 - 4)
  property := by
    dsimp
    sorry

And in fact, since the bijection is going to be a map from \(\mathbb{R}\) to the circle minus the north pole, we must also prove that this expression is not equal to \((0,1)\). Fill in the proof below, using field_simp to simplify the expressions h₁ and h₂. Then find a contradiction.

theorem stereoInvFun_ne_north_pole (w : ) : stereoInvFun w  (⟨(0, 1), by simp : 𝕊) := by
  refine Subtype.coe_ne_coe.1 ?_
  dsimp
  rw [Prod.mk.inj_iff]
  rintro h₁, h₂
  sorry

Now comes the hardest part, proving that the given expression is a left inverse for the forward direction. There are two different denominator expressions which appear: \(1-y\) and \(\left(\frac{2x}{1 - y}\right) ^ 2 + 4\). You will need to prove the nonzeroness of the first one explicitly. For the second, the nonzeroness will be proved automatically by field_simp, since it is clearly strictly positive.

theorem stereo_left_inv {p : 𝕊} (hp : (p :  × )  (0, 1)) :
    stereoInvFun (stereoToFun p) = p := by
  ext1
  obtain ⟨⟨x, y⟩, pythag := p
  dsimp at pythag hp 
  rw [Prod.mk.inj_iff] at hp 
  sorry

The right inverse proof is much easier, it’s another case where field_simp can check the denominator-nonzeroness silently.

theorem stereo_right_inv (w : ) : stereoToFun (stereoInvFun w) = w := by
  dsimp
  sorry

Putting all these facts together with a bit of Lean abstract nonsense gives the bijection.

/-- Stereographic projection, as a bijection to `ℝ` from the complement of `(0, 1)` in the
unit circle `𝕊` in `ℝ × ℝ`. -/
def stereographicProjection : ({(⟨(0, 1), by simp : 𝕊)} : Set 𝕊)   where
  toFun := stereoToFun  (·)
  invFun w := stereoInvFun w, stereoInvFun_ne_north_pole w
  left_inv p := Subtype.coe_injective <| stereo_left_inv (Subtype.coe_injective.ne p.prop)
  right_inv w := stereo_right_inv w

4.3. A binomial coefficient identity

In this section we prove the following identity involving binomial coefficients:

Proposition

For all natural numbers \(i\) and \(j\),

\[\begin{split}&\frac{i - j + 1}{2 (i + j + 1) (i + j + 2)} {2(i+1) \choose i+1} {2j\choose j} - \frac{i - j - 1}{2 (i + j + 1) (i + j + 2)} {2i \choose i} {2 (j + 1) \choose j + 1} \\ &= \frac{ 1}{(i + 1)(j + 1)} { 2i \choose i}{ 2j \choose j}.\end{split}\]

This identity can be discovered by applying the “Gosper algorithm” to the right-hand side. It turns up in Mathlib in the proof that the recursive definition of the Catalan numbers agrees with the definition by binomial coefficients.

The “central binomial coefficient” expressions \({2n \choose n}\) are available in Mathlib under the name

#check @Nat.centralBinom
-- Nat.centralBinom : ℕ → ℕ

and the following easy identity, relating successive central binomial coefficients, is available in Mathlib under the name Nat.succ_mul_centralBinom_succ.

Lemma

For all natural numbers \(n\),

\[(n + 1){2(n+1)\choose n+1} = 2 (2 n + 1) {2n \choose n}.\]

The technique of the proof is pretty clear. One should invoke the above lemma twice, once to turn all \({2(i+1)\choose i+1}\) into \({2i\choose i}\) and once to turn all \({2(j+1)\choose j+1}\) into \({2j\choose j}\). We should therefore first state these two applications of the lemma, then use field_simp to clear denominators and then polyrith to figure out the coefficients with which to combine them. field_simp will check along the way that all the denominators we want to clear are nonzero (since they are all of the form “natural number plus one”).

There is one main complication. The lemma Nat.succ_mul_centralBinom_succ concerns natural numbers, whereas our goal (which involves divisions) is stated as an equality of rational numbers. So each of the applications of the above lemmas will need to be cast – try using the tactic qify for this.

example {i j : } :
    ((i + 1).centralBinom : )
      * j.centralBinom * (i - j + 1) / (2 * (i + j + 1) * (i + j + 2))
    - i.centralBinom * (j + 1).centralBinom
      * (i - j - 1) / (2 * (i + j + 1) * (i + j + 2))
    = i.centralBinom / (i + 1) * (j.centralBinom / (j + 1)) := by
  have h₁ := i.succ_mul_centralBinom_succ
  have h₂ := j.succ_mul_centralBinom_succ
  sorry