(* ** Course: Concepts of Programming Languages (BU CAS CS 320) ** Semester: Summer I, 2009 ** Instructor: Hongwei Xi (hwxi AT cs DOT bu DOT edu) *) // // assgn1ex4.dats // (* ****** ****** *) staload "assignment1.sats" (* ****** ****** *) #define N 100000000 (* ****** ****** *) typedef int4 = @(int, int, int, int) abst@ype mat2x2_t = int4 extern val fib_mat2x2 : mat2x2_t extern val unit_mat2x2 : mat2x2_t extern fun mul_mat2x2_mat2x2 (x: mat2x2_t, y: mat2x2_t): mat2x2_t overload * with mul_mat2x2_mat2x2 extern fun mat2x2_get_11 (x: mat2x2_t): int extern fun mat2x2_get_12 (x: mat2x2_t): int extern fun mat2x2_get_21 (x: mat2x2_t): int extern fun mat2x2_get_22 (x: mat2x2_t): int (* ****** ****** *) local assume mat2x2_t = int4 fun add (x: int, y: int): int = (x + y) mod N fun mul (x: int, y: int): int = let #define i64 int64_of_int val xy64 = (i64 x * i64 y) mod (i64 N) in int_of_int64 (xy64) end // end of [mul] in implement fib_mat2x2 = (0, 1, 1, 1) implement unit_mat2x2 = (1, 0, 0, 1) implement mul_mat2x2_mat2x2 (x, y) = let val (x11, x12, x21, x22) = x val (y11, y12, y21, y22) = y val z11 = (x11 \mul y11) \add (x12 \mul y12) val z12 = (x11 \mul y21) \add (x12 \mul y22) val z21 = (x21 \mul y11) \add (x22 \mul y12) val z22 = (x21 \mul y21) \add (x22 \mul y22) in (z11, z12, z21, z22) end // end of [mul_int4_int4] implement mat2x2_get_11 (x) = x.0 implement mat2x2_get_12 (x) = x.1 implement mat2x2_get_21 (x) = x.2 implement mat2x2_get_22 (x) = x.3 end // end of [val] (* ****** ****** *) fun pow_mat2x2_int (x: mat2x2_t, n: int): mat2x2_t = let fun loop (x: mat2x2_t, n: int, res: mat2x2_t): mat2x2_t = if n >= 2 then let val n2 = n / 2 in if n > n2 + n2 then loop (x * x, n2, x * res) else loop (x * x, n2, res) end else begin if n >= 1 then x * res else res end // end of [if] // end of [loop] in loop (x, n, unit_mat2x2) end // end of [pow_mat2x2_int] (* ****** ****** *) implement fastfib (n) = begin mat2x2_get_12 (pow_mat2x2_int (fib_mat2x2, n)) end // end of [fastfib] (* ****** ****** *) (* end of [assgn1ex4_solu.dats] *)