File: isqrt.dats

package info (click to toggle)
ats2-lang 0.1.3-1
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 28,136 kB
  • ctags: 20,441
  • sloc: ansic: 354,696; makefile: 2,679; sh: 638
file content (105 lines) | stat: -rw-r--r-- 2,684 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
(*
** A verfied implementation of the integer sqare root function
** that is non-tail-recursive and of logarithmic time complexity
**
** Author: Hongwei Xi
** Authoremail: hwxi AT cs DOT bu DOT edu
** Time: November, 2009
*)

(* ****** ****** *)
//
// The code is ported to ATS2 by Hongwei Xi on Friday, July 20, 2012
//
(* ****** ****** *)

staload _ = "prelude/DATS/integer.dats"

(* ****** ****** *)

propdef
ISQRT (x: int, n: int) =
  [x0,x1:nat | x0 <= x; x < x1] (MUL (n, n, x0), MUL (n+1, n+1, x1))
// end of [SQRT]

extern
prfun ISQRT_4_lemma {x:nat} {n2:nat}
  (pf: ISQRT (x/4, n2)): [n:int | 2*n2 <= n; n <= 2*n2+1] ISQRT (x, n)
// end of [ISQRT_4_lemma]

primplmnt
ISQRT_4_lemma // nonrec
  {x} {n2} ([x0:int,x1:int] pf) = let
  prval pf0 = pf.0 // MUL (n2, n2, x0) // x0 <= x/4
  prval pf1 = pf.1 // MUL (n2+1, n2+1, x1) // x/4 < x1
  prval pf1_alt = mul_expand_linear {1,1} {1,1} (pf0)
  prval () = mul_isfun (pf1, pf1_alt)
  stadef n_1 = n2 + n2
  stadef n_2 = n_1 + 1 and n_3 = n_1 + 2
  prval pf0_1 = mul_expand_linear {2,0} {2,0} (pf0)
  stadef x_2 = 4 * x0 + 4 * n2 + 1
  prval pf0_2 = mul_expand_linear {1,1} {1,1} (pf0_1)
  prval pf0_3 = mul_expand_linear {1,2} {1,2} (pf0_1)
in
  sif (x < x_2) then #[n_1 | (pf0_1, pf0_2)] else #[n_2 | (pf0_2, pf0_3)]
end // end of [ISORT_4_lemma]

(* ****** ****** *)

extern // 10 points
fun isqrt {x:nat}
  (x: int x):<> [n:nat] (ISQRT (x, n) | int n)
// end of [isqrt]

implement isqrt (x) = let
//
fun aux {x:nat}.<x>. // non-tail-recursive
  (x: int x):<> [n:nat] (ISQRT (x, n) | int n) =
  if x > 0 then let
    val x4 = x \ndiv 4
    val [n2:int] (pf4 | n2) = aux (x4)
    prval [n:int] pf = ISQRT_4_lemma {x} {n2} (pf4)
    val n_1 = n2 + n2
    val n_2 = n_1 + 1
    val (pf_mul | x1) = g1int_mul2 (n_2, n_2)
  in
    if x < x1 then let
      prval () = (
        sif (n==2*n2) then () else let
          prval () = mul_isfun (pf_mul, pf.0) in (*nothing*)
        end // end of [sif]
      ) : [n==2*n2] void
    in
      (pf | n_1)
    end else let
      prval () = (
        sif (n==2*n2+1) then () else let
          prval () = mul_isfun (pf_mul, pf.1) in (*nothing*)
        end // end of [sif]
      ) : [n==2*n2+1] void
    in
      (pf | n_2)
    end // end of [if]
  end else let
    prval pf0_mul = mul_make {0,0} ()
    prval pf1_mul = mul_make {1,1} ()
  in
    ((pf0_mul, pf1_mul) | 0)
  end // end of [if]
in
  aux (x)
end // end of [isqrt]
      
(* ****** ****** *)

implement
main0 ((*void*)) =
{
  val () = assertloc ( (isqrt(1023)).1 = 31 )
  val () = assertloc ( (isqrt(1024)).1 = 32 )
  val () = assertloc ( (isqrt(1025)).1 = 32 )
} // end of [main0]

(* ****** ****** *)

(* end of [isqrt.dats] *)