agdarational-number

How to prove that the halving function over positive rationals always has an existential?


open import Data.Nat using (ℕ;suc;zero)
open import Data.Rational
open import Data.Product
open import Relation.Nullary
open import Data.Bool using (Bool;false;true)

halve : ℕ → ℚ
halve zero = 1ℚ
halve (suc p) = ½ * halve p

∃-halve : ∀ {a b} → 0ℚ < a → a < b → ∃[ p ] (halve p * b < a)
∃-halve {a} {b} 0<a a<b = h 1 where
  h : ℕ → ∃[ p ] (halve p * b < a)
  h p with halve p * b <? a
  h p | .true because ofʸ b'<a = p , b'<a
  h p | .false because ofⁿ ¬b'<a = h (suc p)

The termination checker fails in that last case and it is no wonder as the recursion obviously is neither well funded nor structural. Nevertheless, I am quite sure this should be valid, but have no idea how to prove the termination of ∃-halve. Any advice for how this might be done?


Solution

  • When you’re stuck on a lemma like this, a good general principle is to forget Agda and its technicalities for a minute. How would you prove it in ordinary human-readable mathematical prose, in as elementary way as possible?

    Your “iterated halving” function is computing b/(2^p). So you’re trying to show: for any positive rationals a, b, there is some natural p such that b/(2^p) < a. This inequality is equivalent to 2^p > b/a. You can break this down into two steps: find some natural nb/a, and then find some p such that 2^p > n.

    As mentioned in comments, a natural way to do find such numbers would be to implement the ceiling function and the log_2 function. But as you say, those would be rather a lot of work, and you don’t need them here; you just need existence of such numbers. So you can do the above proof in three steps, each of which is elementary enough for a self-contained Agda proof, requiring only very basic algebraic facts as background: