The Dottie Number

26 Jun 2026

[ examples  Isar  AI  locales  Archive of Formal Proofs  ]

Once upon a time, goes the story, a lady named Dottie got bored and started playing with her calculator, pressing the cosine key over and over again. At first the numbers fluctuated wildly, but over time they always settled down to approximately 0.739085. (This only works if your calculator is set to radians, not degrees.) She had discovered the unique fixed point of the cosine function. The Dottie number has several further properties: it is a global attractor, meaning the limit is the same no matter what number you start with, and it is transcendental. It is a great example for showing off a range of computer algebra techniques in Isabelle, such as differentiation and unlimited precision real computations. Let’s prove those properties just mentioned and calculate (by proof!) its value to 12 decimal places.

Getting started

We begin by defining dottie to be the unique fixed point of cos. But this definition, using the definite descriptor THE, will be good for nothing until both existence and uniqueness of a fixed point have been proved.

definition dottie :: real where
  "dottie  THE x. cos x = x"

Those claims will be proved with the help of the function $g(x)=\cos x - x$. Note that it slopes downwards.

graph of the function cos(x)-x

We can see that it has a unique root near $\frac{\pi}{4}$, but now we have to prove it. Several different theorems need facts about $g$, so to avoid duplication we create a locale where we can work with $g$.

locale Dottie =
  fixes g :: "real  real"
  defines "g  λx::real. cos x - x"

begin

Thanks to the begin, we are now working inside the locale. We have access to the function $g$ and can accumulate facts about it. Our first task is to investigate its derivative.

lemma g_has_negative_deriv:
  assumes "¦t¦  1" 
  shows "d. (g has_real_derivative d) (at t)  d < 0"
proof (intro exI conjI)
  show "(g has_real_derivative (- sin t - 1)) (at t)"
    unfolding g_def by (auto intro!: derivative_eq_intros)
  show "- sin t - 1 < 0"
    using assms pi_gt3 le_arcsin_iff [of _ t] by fastforce
qed

Isabelle is capable of calculating derivatives automatically. The trick, as we see above, is to hit the goal repeatedly with derivative_eq_intros, which is a collection of facts about derivatives of various operators. The effect is practically the same as the schoolbook method. If you know the derivative already, as here, it makes things easier to mention it. Here we prove that the derivative of $g(t)$, which is $-\sin t-1$, is strictly negative over the given interval $[-1,1]$.

Although computer algebra systems are not always sound, we can use them to write correct Isabelle proofs. Via the fundamental theorem of calculus, we can handle tough integrals. We give the hard work to the computer algebra system; Isabelle merely has to take the derivative of the claimed integral and compare that with the original integrand.

Existence

Existence is proved using the intermediate value theorem, which states that a function $g$ that is continuous on a given closed interval $[a,b]$ attains all the points between $g(a)$ and $g(b)$. Our $g$ is continuous. Since $g(0) = 1$ and $g(1) = \cos 1 - 1 < 0$, the IVT yields a point $x \in (0, 1)$ where $g(x) = 0$, which implies $\cos x = x$.

lemma dottie_exists: "x::real. 0 < x  x < 1  cos x = x"
proof -
  have g_cont: "continuous_on {0..1} g"
    unfolding g_def by (intro continuous_intros)
  obtain "g 0 = 1" "g 1 < 0" using cos_1_lt_1 by (simp add: g_def)
  with IVT2'[of g 1 0 0] g_cont
  obtain x where hx: "0  x" "x  1" "g x = 0"
    by (metis less_eq_real_def zero_le_one)
  hence cos_eq: "cos x = x" by (simp add: g_def)
  with hx show ?thesis
    by (metis cos_1_lt_1 cos_zero order_less_le)
qed

In the proof above, we see a trick for proving continuity. It resembles the trick for taking derivatives, only we hit the goal with a different list of theorems, namely continuous_intros. Then we show the $g$ crosses 0 to prove the existence of a fixed point satisfying $0<x<1$.

Uniqueness

We proved above that the derivative of $g(x) = \cos x - x$ is strictly negative for $x \in [-1,1]$, i.e. $g$ is strictly decreasing, so $g$ can have at most one zero on that interval. And since $[-1,1]$, is the range of the cosine function, uniqueness over the entire real line immediately follows.

lemma dottie_unique:
  fixes x y :: real
  assumes "cos x = x" "cos y = y"
  shows "x = y"
proof (rule ccontr)
  assume "x  y"
  have gx: "g x = 0" and gy: "g y = 0" using assms by (auto simp: g_def)
  show False
  proof (cases "¦x¦ > 1  ¦y¦ > 1")
    case True
    then show ?thesis
      by (metis assms abs_cos_le_one not_less)
  next
    case False
    then have "¦x¦  1  ¦y¦  1"
      by simp
    moreover have "x < y  y < x" using x  y by linarith
    ultimately show ?thesis
      using DERIV_neg_imp_decreasing [OF _ g_has_negative_deriv] gx gy
      by force
  qed
qed

More precisely, given the two claimed fixed points, $x$ and $y$, we first trivially establish that both must lie within the interval $[-1,1]$. Then, assuming for contradiction that $x\not=y$, one must be less than the other. So $g(x)<g(y)$ or $g(y)<g(x)$, because the derivative is strictly negative, but we know $g(x) = g(y) = 0$.

Approximating its value

This is a good example of using untrusted sources, such as a calculator, and validating them by formal proof to get an accurate approximation to Dottie.

definition lb::real where "lb  0.739085133215"
definition ub::real where "ub  0.739085133216"

Knowing that the function $g$ is strictly decreasing, we can determine whether a given estimate is a lower bound or an upper bound. We use the approximation proof method, which is based on interval arithmetic to investigate the ordering relationships.

lemma lb_gt: "cos lb > lb"
  unfolding lb_def by (approximation 50)

lemma ub_lt: "cos ub < ub"
  unfolding ub_def by (approximation 50)

Now we can prove that lb is a lower bound, by contradiction and monotonicity reasoning.

lemma lb: "lb < dottie"
proof (rule ccontr)
  assume neg: "¬ lb < dottie"
  have gd: "g lb > 0" 
    using facts lb_gt by (auto simp: g_def)
  show False
    using DERIV_neg_imp_decreasing [OF _ g_has_negative_deriv] facts neg
    by (smt (verit, ccfv_SIG) cos_le_one cos_monotone_0_pi lb_gt pi_gt3)
qed

And analogously, ub is an upper bound.

lemma ub: "ub > dottie"
proof (rule ccontr)
  assume neg: "¬ ub > dottie"
  have gd: "g ub < 0" 
    using facts ub_lt by (auto simp: g_def)
  show False
    using DERIV_neg_imp_decreasing [OF _ g_has_negative_deriv] facts neg
    by (smt (verit) cos_ge_minus_one ub_lt gd g_def)
qed

We have pinned down the Dottie number to 12 decimal places.

Something trivial

All this time, we were continuing to work in the locale because we needed the lemma that the derivative of $g$ is negative. But now, we are finished with $g$ and leave the locale. We can refer to facts proved inside the locale using the prefix Dottie.

end

Since $\cos(\mathit{dottie}) = \mathit{dottie}$ and $\mathit{dottie} \in (0,1)$, and since $\sin^2 x+cos^2x = 1$, we easily get $\sin(\mathit{dottie}) = \sqrt{1 - \mathit{dottie}^2}$. Sledgehammer found this proof automatically.

lemma sin_dottie: "sin dottie = sqrt (1 - dottie2)"
  by (smt (verit) Dottie.facts pi_gt3 sin_cos_sqrt sin_ge_zero)

The cosine function is a contraction map

The next step is to investigate why iterates of the cosine function always converge to the Dottie number. It’s because $\cos$ is a contraction on $[-1,1]$ with Lipschitz constant $\sin 1$, or with less jargon, $\lvert\cos x - \cos y\rvert\le\sin 1\cdot \lvert x-y\rvert$.

Crucially, $0 < \sin 1 < 1$. This is easy to prove, and we could also have used the approximation method.

lemma sin1_bounds: "0 < sin (1::real)" "sin (1::real) < 1"
  using sin_monotone_2pi[of 1 "pi/2"] pi_gt3 by (auto simp: sin_gt_zero_02)

And $\sin 1$ is the Lipschitz constant for $\cos$ because it is an upper bound on all possible values of $\lvert \sin t\rvert$ when $t\in[-1,1]$.

lemma abs_sin_le_sin1:
  assumes "¦t¦  1" shows "¦sin t¦  sin (1::real)"
proof -
  have "1 < pi/2" using pi_gt3 by simp
  then show ?thesis
    by (smt (verit, best) assms sin_minus sin_monotone_2pi_le)
qed

If $x<y$ then there exists $\xi\in(x,y)$ such that $\lvert\cos x - \cos y\rvert\le\lvert\sin \xi\rvert \cdot \lvert x-y\rvert$, by the mean value theorem. Moreover, $\lvert\sin \xi\rvert\le \sin 1$.

lemma cos_contraction_lt:
  fixes x y :: real
  assumes "x < y" "¦x¦  1" "¦y¦  1"
  shows "¦cos x - cos y¦  sin 1 * ¦x - y¦"
proof -
  have cont: "continuous_on {x..y} cos" 
    by (intro continuous_intros)
  have deriv: "((cos::realreal) has_derivative (*) (- sin u)) (at u)" for u :: real
    using DERIV_cos[of u] unfolding has_field_derivative_def by simp
  then obtain ξ where ξ: "ξ  {x<..<y}" "¦cos y - cos x¦  ¦sin ξ¦ * ¦y - x¦"
    using mvt_general[OF x < y cont deriv] by (auto simp: abs_mult)
  have "¦ξ¦  1" 
    using ξ assms by auto
  have "¦cos y - cos x¦  ¦sin ξ¦ * ¦y - x¦"
    using ξ by (simp add: abs_mult)
  also have "  sin 1 * ¦y - x¦"
    by (simp add: ¦ξ¦  1 abs_sin_le_sin1 mult_mono')
  finally show ?thesis
    by (simp add: abs_minus_commute)
qed

Here, by symmetry, we get rid of the assumption $x<y$. This finally establishes $\sin 1$ as the Lipschitz bound.

lemma cos_contraction:
  fixes x y :: real
  assumes "¦x¦  1" "¦y¦  1"
  shows "¦cos x - cos y¦  sin 1 * ¦x - y¦"
  using cos_contraction_lt[of x y] cos_contraction_lt[of y x] assms
  by (cases x y rule: linorder_cases) (auto simp: abs_minus_commute)

The Dottie number is a universal attractor

An attractor is a set of states towards which a dynamical system tends to evolve if started in some larger set, called the basin of attraction. Iterates of the cosine function converge to the Dottie number starting from any real number, so it is a universal attractor. Since we have established the Lipschitz bound for cosine, it is just a matter of putting some pieces together.

Most of our theorems are confined to the interval $[-1,1]$, but that is no problem. After one step, the iteration lands in $[-1,1]$ and stays there.

lemma cos_funpow_in_pm1:
  fixes x0 :: real
  assumes "n  1"
  shows "¦(cos ^^ n) x0¦  1"
proof -
  have "(cos ^^ n) x0 = cos ((cos ^^ (n-1)) x0)"
    using assms funpow.simps
    by (metis One_nat_def Suc_diff_le diff_Suc_Suc diff_zero o_apply)
  then show ?thesis by simp
qed

Once we are within the interval, applying cosine takes us closer to Dottie. In fact, not that much closer: since $\sin 1 \approx 0.841$, convergence is sluggish.

lemma cos_step_to_dottie:
  assumes "¦w¦  1"
  shows "¦cos w - dottie¦  sin 1 * ¦w - dottie¦"
  using Dottie.facts by (metis abs_cos_le_one assms cos_contraction)

Now we iterate the previous step using the obvious induction. The distance to the fixed point, namely Dottie, decays geometrically.

lemma cos_funpow_bound:
  fixes y0 :: real
  assumes "¦y0¦  1"
  shows "¦(cos ^^ n) y0 - dottie¦  (sin 1)^n * ¦y0 - dottie¦"
proof (induction n)
  case 0
  show ?case by simp
next
  case (Suc n)
  have "¦(cos ^^ n) y0¦  1"
    by (metis funpow_0 less_one not_le cos_funpow_in_pm1[of n y0] assms)
  then have "¦(cos ^^ Suc n) y0 - dottie¦  sin 1 * ¦(cos ^^ n) y0 - dottie¦"
    using cos_step_to_dottie by simp
  also have "  sin 1 * ((sin 1)^n * ¦y0 - dottie¦)"
    using Suc.IH sin1_bounds by (simp add: mult_left_mono)
  also have " = (sin 1)^(Suc n) * ¦y0 - dottie¦"
    by (simp add: mult.assoc)
  finally show ?case .
qed

Hence, the series of iterates converges to Dottie.

lemma cos_iter_tendsto_unit:
  fixes y0 :: real
  assumes "¦y0¦  1"
  shows "(λn. (cos ^^ n) y0)  dottie"
proof -
  have pow0: "(λn. (sin 1)^n)  (0::real)"
    using sin1_bounds by (intro LIMSEQ_realpow_zero) auto
  have null: "(λn. (sin 1)^n * ¦y0 - dottie¦)  0"
    using tendsto_mult[OF pow0 tendsto_const, of "¦y0 - dottie¦"] by simp
  have "(λn. ¦(cos ^^ n) y0 - dottie¦)  0"
    using tendsto_sandwich[OF _ _ tendsto_const null] cos_funpow_bound[OF assms] by auto
  then show ?thesis
    using Lim_null tendsto_rabs_zero_iff by blast
qed

Most of the previous results hold only for an initial value within the interval $[-1,1]$. Given an arbitrary initial value $x_0$, noting that $\cos x_0$ lies within that interval yields the desired universal attractor result.

theorem cos_iter_tendsto_dottie:
  fixes x0 :: real
  shows "(λn. (cos ^^ n) x0)  dottie"
proof -
  have "¦cos x0¦  1" by simp
  from cos_iter_tendsto_unit[OF this]
  have "(λn. (cos ^^ n) (cos x0))  dottie" .
  moreover have "n. (cos ^^ n) (cos x0) = (cos ^^ Suc n) x0"
    by (simp add: funpow_swap1)
  ultimately have "(λn. (cos ^^ Suc n) x0)  dottie" by simp
  then show ?thesis
    using filterlim_sequentially_Suc by blast
qed

Transcendence

Finally, let’s note that Dottie is transcendental: not a root of any polynomial with integer coefficients. This turns out to be trivial, thanks to the Archive of Formal Proofs. By the Hermite–Lindemann–Weierstraß theorem, $\cos z$ is transcendental for every nonzero algebraic $z$. And Dottie is nonzero. If Dottie were algebraic, then $\cos(\mathit{dottie}) = \mathit{dottie}$ would be both algebraic and transcendental, contradiction.

theorem dottie_transcendental: "¬ algebraic dottie"
proof
  assume alg: "algebraic dottie"
  then have "¬ algebraic (cos (complex_of_real dottie))"
    using Dottie.facts transcendental_cos by auto 
  moreover have "cos (complex_of_real dottie) = complex_of_real dottie"
    using Dottie.facts by (simp add: cos_of_real)
  ultimately show False using alg by simp
qed

Sledgehammer can do all this automatically, but the proof above is clearer.

A remark on AI

The entry resulted from some experiments using Claude. Claude suggested the Dottie number as a nice simple example. Claude also supplied the first version of the proofs. They were correct as far as they went, but were overly detailed and with major omissions. Notably, Claude forgot to prove that the Dottie number is unique over the entire real line, not just over the interval $[-1,1]$. So a fair bit of hand polishing has gone into these proofs. They can be downloaded from the AFP.