Derivation of a Fast Integer Square Root Algorithm Christoph Kreitz Department of Computer Science, Cornell-University, Ithaca, NY 14853-7501 [email protected] Abstract In a constructive setting, the formula ∀n ∃r r2 ≤n ∧ n<(r+1)2 specifies an algorithm for computing the integer square root r of a natural number x. A proof for this formula implicitly contains an integer square root algorithm that mirrors the way in which the formula was proven correct. In this note we describe the formal derivation of several integer square root algorithms within the Nuprl proof development system and show how efficient algorithms can be derived using advanced induction schemes. 1 Deriving a Linear Algorithm The standard approach to proving ∀n ∃r r2 ≤n the following two proof goals ∧ n<(r+1)2 is induction on n, which will lead to Base Case: prove ∃r r2 ≤0 ∧ 0<(r+1)2 Induction Step: prove ∃r r2 ≤n+1 ∧ n+1<(r+1)2 assuming ∃rn r2 ≤n ∧ n<(rn +1)2 . The base case can be solved by choosing r = 0 and using standard arithmetical reasoning to prove the resulting proof obligation 02 ≤0 ∧ 0<(0+1)2 . In the induction step, one has to analyze the root rn . If (rn +1)2 ≤n+1, then choosing r = rn +1 will solve the goal. Again, the proof obligation (rn +1)2 ≤n+1 ∧ n+1<((rn +1)+1)2 can be shown by standard arithmetical reasoning. (rn +1)2 > n+1, then one has to choose r = rn and prove rn2 ≤n+1 ∧ n+1<(rn +1)2 using standard arithmetical reasoning. Figure 1 shows the trace of a formal proof in the Nuprl system [CAB+ 86, ACE+ 00] that uses exactly this line of argument. It initiates the induction by applying the library theorem NatInd ∀P:N→P. (P(0) ∧ (∀i:N+ . P(i-1) ⇒ P(i))) ⇒ (∀i:N. P(i)) The base case is solved by assigning 0 to the existentially quantified variable and using Nuprl’s autotactic (trivial standard reasoning) to deal with the remaining proof obligation. In the step case (from i−1 to i) it analyzes the root r for i−1, introduces a case distinction on (r+1)2 ≤i and then assigns either r or r+1, again using Nuprl’s autotactic on the rest of the proof. Nuprl is capable of extracting an algorithm from the formal proof, which then may be run within Nuprl’s computation environment or be exported to other programming systems. The algorithm is represented in Nuprl’s extended lambda calculus. Depending on the formalization of the existential quantifier there are two kinds of algorithms that may be extracted. In the standard formalization, where ∃ is represented as a (dependent) 1 ∀n:N. ∃r:N. BY allR r2 ≤ n < (r+1)2 n:N ` ∃r:N. r2 ≤ n < (r+1)2 BY NatInd 1 .....basecase..... ` ∃r:N. r2 ≤ 0 < (r+1)2 √ BY existsR d0e THEN Auto .....upcase..... i:N+ , r:N, r2 ≤ i-1 < (r+1)2 ` ∃r:N. r2 ≤ i < (r+1)2 BY Decide d(r+1)2 ≤ ie THEN Auto .....Case 1..... i:N+ , r:N, r2 ≤ i-1 < (r+1)2 , ` ∃r:N. r2 ≤ i < (r+1)2 √ BY existsR dr+1e THEN Auto’ .....Case 2..... i:N+ , r:N, r2 ≤ i-1 < (r+1)2 , ` ∃r:N. r2 ≤ i < (r+1)2 √ BY existsR dre THEN Auto (r+1)2 ≤ i ¬((r+1)2 ≤ i) Figure 1: Proof of the Specification Theorem using Standard Induction. product type, the algorithm – shown on the left1 – computes both the integer square root r of a given natural number n and a proof term, which verifies that r is in fact the integer square root of n. If ∃ is represented as a set type, this verification information is dropped during extraction and the algorithm – shown on the right – only performs the computation of the integer square root. let rec sqrt n = if n=0 then 0 else let r = sqrt (n-1) in if (r+1)2 ≤n then r+1 else r let rec sqrt n = if n=0 then <0,pf 0> else let <r,pfi−1 > = sqrt (n-1) in if (r+1)2 ≤n then <r+1,pf n> else <r,pf n’> Using standard conversion mechanisms, Nuprl can then transform the algorithm into any programming language that supports recursive definition and export it to the corresponding programming environment. As this makes little sense for algorithms containing proof terms, we only convert the algorithm on the right. A conversion into SML, for instance, yields the following program. fun sqrt n = if n=0 then 0 else let val r = sqrt (n-1) in if n < (r+1)ˆ2 then r else r+1 end 1 The place holders pfk represent the actual proof terms that are irrelevant for the computation. 2 2 √ Deriving an Algorithm that runs in O( n) Due to the use of standard induction on the input variable, the algorithm derived in the previous section is linear in the size of the input n, which is reduced by 1 in each step. Obviously, this is not the most efficient way to compute an integer square root. In the following we will derive more efficient algorithms by proving ∀n ∃r r2 ≤n ∧ n<(r+1)2 in a different way. These proof, however, will have to rely on more complex induction schemes to ensure a more efficient computation. A more common method to compute the integer square root of a given number n is to start a search for a possible result r. One starts with r=0 and then increases r until (r+1)2 > n. In the context of a proof, this means that we need to introduce an auxiliary variable k for the search and perform induction on this variable instead of n. ∀n:N. ∃r:N. r2 ≤ n < (r+1)2 BY allR THEN Assert d∀j:N. (n-j)2 ≤n ⇒ ∃r≥n-j. r2 ≤ n < (r+1)2 e .....Assertion..... n:N, j:N, (n-j)2 ≤n ` ∃r≥n-j. r2 ≤ n < (r+1)2 BY NatInd 2 .....basecase..... n:N, (n-0)2 ≤n ` ∃r≥n-0. r2 ≤ n < (r+1)2 √ BY existsR dne THEN Auto’ .....upcase..... n:N, j:N+ , (n-(j-1))2 ≤n ⇒ ∃r≥n-(j-1). r2 ≤ n < (r+1)2 , (n-j)2 ≤n ` ∃r≥n-j. r2 ≤ n < (r+1)2 BY Decide dn < (n-j+1)2 e THEN Auto .....Case 1..... n:N, j:N+ , (n-(j-1))2 ≤n ⇒ ∃r≥n-(j-1). r2 ≤ n < (r+1)2 , (n-j)2 ≤n, n < (n-j+1)2 ` ∃r≥n-j. r2 ≤ n < (r+1)2 √ BY existsR dn-je THEN Auto’ .....Case 2..... n:N, j:N+ , (n-(j-1))2 ≤n ⇒ ∃r≥n-(j-1). r2 ≤ n < (r+1)2 , (n-j)2 ≤n ¬(n < (n-j+1)2 ) ` ∃r≥n-j. r2 ≤ n < (r+1)2 BY impL 3 THEN Auto √ n:N, j:N+ , (n-(j-1))2 ≤n ⇒ ∃r≥n-(j-1). r2 ≤ n < (r+1)2 , ¬(n < (n-j+1)2 ) ` ∃r≥n-j. r2 ≤ n < (r+1)2 BY existsR dre THEN Auto’ .....Main..... n:N, ∀j:N. (n-j)2 ≤n ⇒ ∃r≥n-j. r2 ≤ n < (r+1)2 ` ∃r:N. r2 ≤ n < (r+1)2 BY allL 2 dne THEN Auto √ n:N, r:N, r≥n-n, r2 ≤ n < (r+1)2 ` ∃r:N. r2 ≤ n < (r+1)2 BY existsR dre THEN Auto Figure 2: Proof of the Specification Theorem using Search 3 (n-j)2 ≤n A naive approach would be to prove the theorem ∀n ∀k ∃r≥k r2 ≤n ∧ n<(r+1)2 using induction on k and then to instantiate this theorem with k=0. This approach, however, has two major flaws. First, the induction on k expresses a solution for k in terms of a solution for k−1, which is less √ efficient than a forward search. Second, the search must begin at some k> n but the theorem √ obviously does not hold for k> n. To fix these problems, we need to change the direction of the search into one that starts at 0 and recursively solves the problem for k by consulting a solution for k+1 until the square root has been found, which can be expressed by a standard induction over j = n−k. We also need to add a limit to the search, i.e. (n−j)2 =k 2 ≤n. The formal Nuprl proof begins by asserting ∀j (n−j)2 ≤n ⇒ ∃r≥(n−j) r2 ≤n ∧ n<(r+1)2 , proves this statement by induction, and then instantiates it with j=n. Extracting the algorithm from this proof, depicted in Figure 2, and converting it into SML leads to the following program, √ which now runs in O( n). fun sqrt n = let fun aux j = if j=0 then n if n < (n-j+1)ˆ2 else aux (j-1) in aux n end then n-j Note that the case j=0 is never reached unless n is 0. By using different induction schemes it is possible to modify this algorithm into a more conventional form that uses an auxiliary variable k that is increasing instead of the term n−j, where j is decreasing. This induction scheme, however, needs to make explicit that choices for the auxiliary variable have an upper bound (i.e. n), whereas the lower bound zero is implicit in the other induction schemes that quantify over natural numbers. The induction scheme RevNatInd ∀P:N→P. (∀i:{...t}. (∀j:{i+1..t}. P(j)) ⇒ P(i)) ⇒ (∀i:{...t}. P(i)) which can easily be derived from the scheme NatInd, enables us to begin our proof by asserting ∀k k 2 ≤n ⇒ ∃r≥k r2 ≤n ∧ n<(r+1)2 and then to proceed as in Figure 2, replacing every occurrence of n−j by k. The extracted algorithm would now be fun sqrt n = let fun aux k = if k=n then n if n < (k+1)ˆ2 else aux (k+1) in aux 0 end then y Actually, the search algorithm is an instance of a generic search method that is implicitly contained in the following theorem NatSearch ∀P:N→P. ∀n:N. P(n) ⇒ (∃k:{0..n}. P(k) ∧ (∀j:{0..k-1}. ¬P(j))) which states the (bounded) existence of a minimal k with some property P . Instantiating this theorem with P (k) replaced by (k + 1)2 > n immediately gives us the desired search algorithm. 4 ∀n:N. ∃r:N. BY allR r2 ≤ n < (r+1)2 n:N ` ∃r:N. r2 ≤ n < (r+1)2 BY NatInd4 1 .....basecase..... ` ∃r:N. r2 ≤ 0 < (r+1)2 √ BY existsR d0e THEN Auto .....upcase..... i:N, r:N, r2 ≤ i÷4 < (r+1)2 ` ∃r:N. r2 ≤ i < (r+1)2 BY Decide d((2*r)+1)2 ≤ ie THEN Auto .....Case 1..... i:N, r:N, r2 ≤ i÷4 < (r+1)2 , ((2*r)+1)2 ≤ i ` ∃r:N. r2 ≤ i < (r+1)2 √ BY existsR d(2*r)+1e THEN Auto’ .....Case 2..... i:N, r:N, r2 ≤ i÷4 < (r+1)2 , ` ∃r:N. r2 ≤ i < (r+1)2 √ BY existsR d2*re THEN Auto ¬(((2*r)+1)2 ≤ i) Figure 3: Proof of the Specification Theorem using Binary Induction 3 Deriving a Logarithmic Algorithm One of the most efficient forms of computation on numbers is to operate on their binary representation and to construct a value bit by bit. The corresponding induction scheme requires proving a conclusion P (x) from an induction hypothesis P (x÷2), where ÷ denotes integer division. For the integer square root problem, this induction scheme would have to be used on the output variable similarly to the way linear induction was used in the previous section. It is much easierr, however, to use 4-adic induction on the input variable instead, as this leads to a simpler proof. In fact, it is possible to mirror the proof given in Section 1 by applying the library theorem NatInd4 ∀P:N→P. (P(0) ∧ (∀i:N. P(i÷4) ⇒ P(i))) ⇒ (∀i:N. P(i)) and then replacing every occurrence of r in the arguments of a proof tactic by 2*r. Apart from these differences, which are emphasized in both proofs, the proof in Figure 3 is identical to the one in Figure 1. Accordingly, the generated algorithms have exactly the same structure. Extracting the algorithm from the proof in Figure 3 and converting it into SML leads to the following program, which now runs in logarithmic time (assuming that division by 4 is implemented as bit-shift operation). fun sqrt n = if n=0 then 0 else let val r = sqrt (n/4) in if n < (2*r+1)ˆ2 then 2*r else 2*r+1 end 5 Final Remarks The algorithms and derivations presented in this note are contained in Nuprl’s formal digital library that is now available online for interactive browsing at http://www.nuprl.org. Using the proof strategies for inductive reasoning described in [KP01] it is possible to automatically construct all the proofs presented here. The implementation of this method as well as the proofs generated by it will be posted as part of the formal digital library in the future. This work was supported in part by the DoD Multidisciplinary University Research Initiative (MURI) program administered by the Office of Naval Research (ONR) under Grant N00014-01-10765 (Building Interactive Digital Libraries of Formal Algorithmic Knowledge) and by NSF Grant CCR 0204193 (Proof Automation in Constructive Type Theory). References [ACE+ 00] Stuart Allen, Robert Constable, Richard Eaton, Christoph Kreitz, and Lori Lorigo. The Nuprl open logical environment. In D. McAllester, editor, 17th Conference on Automated Deduction, volume 1831 of Lecture Notes in Artificial Intelligence, pages 170–176. Springer Verlag, 2000. [CAB+ 86] Robert L. Constable, Stuart F. Allen, H. Mark Bromley, W. Rance Cleaveland, J. F. Cremer, Robert W. Harper, Douglas J. Howe, Todd B. Knoblock, Nax Paul Mendler, Prakash Panangaden, Jim T. Sasaki, and Scott F. Smith. Implementing Mathematics with the Nuprl proof development system. Prentice Hall, 1986. [KP01] Christoph Kreitz and Brigitte Pientka. Connection-driven inductive theorem proving. Studia Logica, 69(2):293–326, 2001. 6
© Copyright 2026 Paperzz