[MLton-commit] r4986

Wesley Terpstra wesley at mlton.org
Mon Dec 18 18:59:17 PST 2006


import didn't work, try adding and commiting
----------------------------------------------------------------------

A   mltonlib/trunk/ca/terpstra/math/README
A   mltonlib/trunk/ca/terpstra/math/algebra.fun
A   mltonlib/trunk/ca/terpstra/math/algebra.sig
A   mltonlib/trunk/ca/terpstra/math/c.fun
A   mltonlib/trunk/ca/terpstra/math/c.sml
A   mltonlib/trunk/ca/terpstra/math/factor.fun
A   mltonlib/trunk/ca/terpstra/math/factor.sml
A   mltonlib/trunk/ca/terpstra/math/galois.fun
A   mltonlib/trunk/ca/terpstra/math/galois.sml
A   mltonlib/trunk/ca/terpstra/math/gcd.fun
A   mltonlib/trunk/ca/terpstra/math/groups.fun
A   mltonlib/trunk/ca/terpstra/math/groups.sig
A   mltonlib/trunk/ca/terpstra/math/log.fun
A   mltonlib/trunk/ca/terpstra/math/math.mlb
A   mltonlib/trunk/ca/terpstra/math/mersenne.fun
A   mltonlib/trunk/ca/terpstra/math/mersenne.sml
A   mltonlib/trunk/ca/terpstra/math/ops.sig
A   mltonlib/trunk/ca/terpstra/math/ops.sml
A   mltonlib/trunk/ca/terpstra/math/order.sml
A   mltonlib/trunk/ca/terpstra/math/permutation.sml
A   mltonlib/trunk/ca/terpstra/math/polynomial.fun
A   mltonlib/trunk/ca/terpstra/math/q.fun
A   mltonlib/trunk/ca/terpstra/math/q.sml
A   mltonlib/trunk/ca/terpstra/math/r.fun
A   mltonlib/trunk/ca/terpstra/math/r.sml
A   mltonlib/trunk/ca/terpstra/math/rings.fun
A   mltonlib/trunk/ca/terpstra/math/rings.sig
A   mltonlib/trunk/ca/terpstra/math/test/
A   mltonlib/trunk/ca/terpstra/math/test/test.mlb
A   mltonlib/trunk/ca/terpstra/math/test/test.sml
A   mltonlib/trunk/ca/terpstra/math/test/test2.sml
A   mltonlib/trunk/ca/terpstra/math/test/test3.mlb
A   mltonlib/trunk/ca/terpstra/math/test/test3.sml
A   mltonlib/trunk/ca/terpstra/math/test/test4.mlb
A   mltonlib/trunk/ca/terpstra/math/test/test4.sml
A   mltonlib/trunk/ca/terpstra/math/z.fun
A   mltonlib/trunk/ca/terpstra/math/z.sml

----------------------------------------------------------------------

Added: mltonlib/trunk/ca/terpstra/math/README
===================================================================
--- mltonlib/trunk/ca/terpstra/math/README	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/README	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,44 @@
+This is an incomplete library for number theory.
+
+What there is:
+	small-size galois fields
+	mersenne fields
+	polynomials with Karatsuba (no FFT)
+	permutations
+	generic methods (gcd, discrete logarithm, ...)
+	a reasonably fast integer factorization algorithm
+
+Basically, it's a framework in which I dumped any algorithms or mathematical
+structures I needed as I needed them.
+
+Using it is pretty nice, since you can bind any structure to an operation.
+Generally, one combines functors to create the desired mathematical object.
+
+Some objects already exist (Z = integers, Galois8 = GF(8))
+Some need to be created, eg: ComplexOfField(FieldOfReal(LargeReal))
+
+Structures contain their mathematical operations and substructures.
+The structure Z includes substructures Z.Addition (an abelian group) and 
+Z.Multiplication (an abelian monoid). These include relevant operations.
+
+Once a structure has been created, it can be bound to an operation.
+For example:
+	structure Binding = AbelianGroupAddPercent(Z.Addition)
+	open Binding
+will bind =%, +%, -%, ~%, and ++% operations for manipulating Z elements.
+
+To bind the entire structure of Z, one can use:
+	structure Binding = EuclideanDomainDollar(Z)
+	open Binding
+This binds operations: =$, !=$, *$, **$, /$, %$, //$, +$, -$, ~$
+
+There are also some generic algorithms, for example:
+	structure G = GCD(Z)
+This gives you a GCD method that works over integers.
+
+Another example:
+	structure P = PolynomialOverField(ComplexOfField(FieldOfReal(LargeReal)))
+	structure B = Polynomial(P)
+	open B
+Here, the operations with % on the end operate on complex values, while $
+operates on polynomials over the complex numbers.

Added: mltonlib/trunk/ca/terpstra/math/algebra.fun
===================================================================
--- mltonlib/trunk/ca/terpstra/math/algebra.fun	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/algebra.fun	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,69 @@
+(****************************************************************** Algebra ops *)
+
+functor ScalarMultiply(S : SCALAR_MULTIPLY) =
+  struct
+    val (op *&) = S.MUL
+  end
+
+functor Module(M : MODULE) =
+  struct
+    local structure S = RingPercent(M.Base) in open S end
+    local structure S = AbelianGroupAddDollar(M.Addition) in open S end
+    local structure S = ScalarMultiply(M.ScalarMultiplication) in open S end
+  end
+
+functor UnitaryModule(U : UNITARY_MODULE) =
+  struct
+    local structure S = UnitaryRingPercent(U.Base) in open S end
+    local structure S = AbelianGroupAddDollar(U.Addition) in open S end
+    local structure S = ScalarMultiply(U.ScalarMultiplication) in open S end
+  end
+
+functor VectorSpace(V : VECTOR_SPACE) =
+  struct
+    local structure S = FieldPercent(V.Base) in open S end
+    local structure S = AbelianGroupAddDollar(V.Addition) in open S end
+    local structure S = ScalarMultiply(V.ScalarMultiplication) in open S end
+  end
+
+functor Algebra(A : ALGEBRA) =
+  struct
+    local structure S = CommutativeRingPercent(A.Base) in open S end
+    local structure S = NonAssociativeRingDollar(A) in open S end
+    local structure S = ScalarMultiply(A.ScalarMultiplication) in open S end
+  end
+
+functor FieldAlgebra(A : FIELD_ALGEBRA) =
+  struct
+    local structure S = FieldPercent(A.Base) in open S end
+    local structure S = NonAssociativeRingDollar(A) in open S end
+    local structure S = ScalarMultiply(A.ScalarMultiplication) in open S end
+  end
+
+functor AssociativeAlgebra(A : ASSOCIATIVE_ALGEBRA) =
+  struct
+    local structure S = CommutativeRingPercent(A.Base) in open S end
+    local structure S = RingDollar(A) in open S end
+    local structure S = ScalarMultiply(A.ScalarMultiplication) in open S end
+  end
+
+functor AssociativeFieldAlgebra(A : ASSOCIATIVE_FIELD_ALGEBRA) =
+  struct
+    local structure S = FieldPercent(A.Base) in open S end
+    local structure S = RingDollar(A) in open S end
+    local structure S = ScalarMultiply(A.ScalarMultiplication) in open S end
+  end
+
+functor UnitaryAssociativeAlgebra(A : UNITARY_ASSOCIATIVE_ALGEBRA) =
+  struct
+    local structure S = CommutativeRingPercent(A.Base) in open S end
+    local structure S = UnitaryRingDollar(A) in open S end
+    local structure S = ScalarMultiply(A.ScalarMultiplication) in open S end
+  end
+
+functor UnitaryAssociativeFieldAlgebra(A : UNITARY_ASSOCIATIVE_FIELD_ALGEBRA) =
+  struct
+    local structure S = FieldPercent(A.Base) in open S end
+    local structure S = UnitaryRingDollar(A) in open S end
+    local structure S = ScalarMultiply(A.ScalarMultiplication) in open S end
+  end

Added: mltonlib/trunk/ca/terpstra/math/algebra.sig
===================================================================
--- mltonlib/trunk/ca/terpstra/math/algebra.sig	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/algebra.sig	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,103 @@
+signature SCALAR_MULTIPLY = 
+  sig
+    type e
+    type t
+    
+    (* if one exists: one*v = v*one = v *)
+    val MUL: e * t -> t
+    
+    (* a*(b*v) = (a*.b)*v *)
+    val associative : unit
+    
+    (* c*(v+w) = c*v + v*w
+     * (c+.d)*v = c*v + d*v
+     *)
+    val distributive : unit
+  end
+
+(* All MODULEs here are left modules *)
+signature MODULE =
+  sig
+    type e 
+    type t
+    structure Base : RING where type t = e
+    structure Addition : ABELIAN_GROUP where type t = t
+    structure ScalarMultiplication : SCALAR_MULTIPLY where type e = e and type t = t
+  end
+
+signature UNITARY_MODULE =
+  sig
+    type e 
+    type t
+    structure Base : UNITARY_RING where type t = e
+    structure Addition : ABELIAN_GROUP where type t = t
+    structure ScalarMultiplication : SCALAR_MULTIPLY where type e = e and type t = t
+  end
+
+(* same as a UNITARY_MODULE, but over a field *)
+signature VECTOR_SPACE =
+  sig
+    type e 
+    type t
+    structure Base : FIELD where type t = e
+    structure Addition : ABELIAN_GROUP where type t = t
+    structure ScalarMultiplication : SCALAR_MULTIPLY where type e = e and type t = t
+  end
+
+signature ALGEBRA =
+  sig
+    include NON_ASSOCIATIVE_RING
+    type e 
+    structure Base : COMMUTATIVE_RING where type t = e
+    structure ScalarMultiplication : SCALAR_MULTIPLY where type e = e and type t = t
+    
+    (* (ax)y = a(xy)
+     * a(xy) = x(ay)
+     *)
+    val bilinear : unit
+  end
+
+signature FIELD_ALGEBRA =
+  sig
+    include NON_ASSOCIATIVE_RING
+    type e 
+    structure Base : FIELD where type t = e
+    structure ScalarMultiplication : SCALAR_MULTIPLY where type e = e and type t = t
+    val bilinear : unit
+  end
+
+signature ASSOCIATIVE_ALGEBRA =
+  sig
+    include RING
+    type e 
+    structure Base : COMMUTATIVE_RING where type t = e
+    structure ScalarMultiplication : SCALAR_MULTIPLY where type e = e and type t = t
+    val bilinear : unit
+  end
+
+signature ASSOCIATIVE_FIELD_ALGEBRA =
+  sig
+    include RING
+    type e 
+    structure Base : FIELD where type t = e
+    structure ScalarMultiplication : SCALAR_MULTIPLY where type e = e and type t = t
+    val bilinear : unit
+  end
+
+signature UNITARY_ASSOCIATIVE_ALGEBRA =
+  sig
+    include UNITARY_RING
+    type e 
+    structure Base : COMMUTATIVE_RING where type t = e
+    structure ScalarMultiplication : SCALAR_MULTIPLY where type e = e and type t = t
+    val bilinear : unit
+  end
+
+signature UNITARY_ASSOCIATIVE_FIELD_ALGEBRA =
+  sig
+    include UNITARY_RING
+    type e 
+    structure Base : FIELD where type t = e
+    structure ScalarMultiplication : SCALAR_MULTIPLY where type e = e and type t = t
+    val bilinear : unit
+  end

Added: mltonlib/trunk/ca/terpstra/math/c.fun
===================================================================
--- mltonlib/trunk/ca/terpstra/math/c.fun	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/c.fun	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,47 @@
+(* This is still a field only if (x^2 + 1) is irreducible *)
+functor ComplexOfField(F : FIELD) : FIELD =
+  struct
+    local
+      structure B = FieldPercent(F)
+      structure O = EuclideanDomainDollar(Order)
+      open B
+      open O
+    in
+      type t = F.t * F.t
+      val characteristic = F.characteristic
+      
+      structure Addition =
+        struct
+          type t = F.t * F.t
+          val order = F.Addition.order *$ F.Addition.order
+          
+          val associative = ()
+          val commutative = ()
+          val one = (#%0, #%0)
+          
+          val EQ  = fn ((ar, ai), (br, bi)) => (ar =% br) andalso (ai =% bi)
+          val MUL = fn ((ar, ai), (br, bi)) => (ar +% br, ai +% bi)
+          val DIV = fn ((ar, ai), (br, bi)) => (ar -% br, ai -% bi)
+          val INV = fn (a, b) => (~%a, ~%b)
+        end
+        
+      structure Multiplication = 
+        struct
+          type t = F.t * F.t
+          val order = F.Addition.order *$ F.Addition.order -$ #$1
+          
+          val associative = ()
+          val commutative = ()
+          val one = (#%1, #%0)
+          
+          val EQ  = fn ((ar, ai), (br, bi)) => (ar =% br) andalso (ai =% bi)
+          val INV = fn (r, i) => 
+            let val e = !%(r*%r +% i*%i) in (r*%e, ~%i*%e) end
+          val MUL = fn ((ar, ai), (br, bi)) => (ar*%br -% ai*%bi, ar*%bi +% ai*%br)
+          val DIV = fn (a, c) => MUL (a, INV c)
+        end
+      
+      val distributive     = ()
+      val no_zero_divisors = ()
+    end
+  end

Added: mltonlib/trunk/ca/terpstra/math/c.sml
===================================================================
--- mltonlib/trunk/ca/terpstra/math/c.sml	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/c.sml	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,4 @@
+structure C = ComplexOfField(R)
+
+structure C32 = ComplexOfField(R32)
+structure C64 = ComplexOfField(R64)

Added: mltonlib/trunk/ca/terpstra/math/factor.fun
===================================================================
--- mltonlib/trunk/ca/terpstra/math/factor.fun	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/factor.fun	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,22 @@
+functor Factor(E : EUCLIDEAN_DOMAIN) =
+  struct
+    local
+      structure B = EuclideanDomainPercent(E)
+      open B
+      
+      fun push (z, l) =
+        case l of
+          nil => (z, #%1) :: nil
+        | (y, e) :: l => 
+            if y =% z 
+            then (y, e +% #%1) :: l
+            else (z, #%1) :: (y, e) :: l
+          
+      fun niaveFactor (z, l) a =
+        if z <% a*%a then push (z, l) else
+        if z %% a =% #%0 then niaveFactor (z /% a, push (a, l)) a else
+        niaveFactor (z, l) (a +% #%1)
+    in
+      fun factor z = niaveFactor (z, nil) (#%2)
+    end
+  end

Added: mltonlib/trunk/ca/terpstra/math/factor.sml
===================================================================
--- mltonlib/trunk/ca/terpstra/math/factor.sml	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/factor.sml	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,54 @@
+structure Factor =
+  struct
+    local
+      open LargeInt
+    in
+      fun isPrime n =
+        let
+          fun chop (c, e) = if c mod 2 = 0 then chop (c div 2, e+1) else (c, e)
+          val (c, e) = chop (n-1, 0)
+          
+          fun exp (x, 0) = 1
+            | exp (x, 1) = x
+            | exp (x, e) = 
+              let val y = exp (x*x mod n, e div 2)
+              in if e mod 2 = 0 then y else y * x mod n end
+          
+          fun checkPow (w, e) =
+            e > 0 andalso (w+1 = n orelse checkPow (w*w mod n, e-1))
+          fun millerRabin w = 
+            let val v = exp (w, c)
+            in v = 1 orelse checkPow (v, e) end
+        in
+          List.foldl (fn (w, a) => a andalso millerRabin (1 + w mod (n-1))) 
+            true [62151, 7444, 40814, 49239, 71708759, 4481, 665652934 ]
+        end
+      
+      fun factor n =
+        let
+          fun sort nil = nil
+            | sort (p :: r) =
+              let val (s, b) = List.partition (fn x => x < p) r
+              in sort s @ p :: sort b end
+          
+          fun gcd (a, b) = if a = 0 then b else gcd (b mod a, a)
+          
+          fun findafactor n =
+            let
+              val start = Word.toLargeInt (MLton.Random.rand ()) mod n
+              fun f x = (x*x + 2) mod n
+              fun loop x y =
+                let val g = gcd (n, n+x-y)
+                in if g = 1 then loop (f x) (f (f y)) else g end
+            in loop start (f start) end
+          
+          fun suck n l =
+            if n = 1 then l else
+            if isPrime n then n :: l else
+            let val x = findafactor n
+            in suck x (suck (n div x) l) end
+        in
+          sort (suck n [])
+        end
+    end
+  end

Added: mltonlib/trunk/ca/terpstra/math/galois.fun
===================================================================
--- mltonlib/trunk/ca/terpstra/math/galois.fun	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/galois.fun	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,93 @@
+signature GaloisParam =
+  sig
+    structure W : WORD
+    val base : W.word
+  end
+
+functor GaloisFromTable(P : GaloisParam) : FIELD =
+  struct
+    local
+      open P.W
+      open Int
+      
+      val fromInt = P.W.fromInt
+      val toInt   = P.W.toInt
+      
+      val zero = fromInt 0
+      val one  = fromInt 1
+      
+      val msize = toInt (notb zero)
+      val size = msize + 1
+      val highbit = << (one, Word.-(Word.fromInt wordSize, 0w1))
+      
+      fun nastymul x y =
+        if y = zero then zero else
+        if y = one then x else
+        let val h = nastymul x (>> (y, 0w1))
+            val x = if andb (y, one) = one then x else zero
+            val b = if andb (h, highbit) = highbit then P.base else zero
+        in xorb( << (h, 0w1), xorb(x, b)) end
+      
+      val gen = orb (one, << (one, 0w1)) (* x^1 + x^0 <- a generator *)
+      
+      val log = Array.array (size, zero)
+      fun set _ l ~1 = l
+        | set a l i = (
+            Array.update (log, toInt a, fromInt i)
+            ; set (nastymul a gen) (a :: l) (i - 1))
+      
+      val exp = Vector.fromList (set gen nil (msize + msize - 1))
+      val log = Array.vector log
+(*      
+      val _ = Vector.app (fn x => print (P.W.toString x ^ " ")) exp
+      val _ = print "\n"
+      val _ = Vector.app (fn x => print (P.W.toString x ^ " ")) log
+      val _ = print "\n"
+*)      
+      val exp = fn x => Vector.sub (exp, x)
+      val log = fn x => toInt (Vector.sub (log, toInt x))
+    in
+      type t = word
+      val characteristic = LargeInt.fromInt 2
+      
+      structure Addition =
+        struct
+          type t = word
+          val order = FINITE (Int.toLarge msize)
+          
+          val associative = ()
+          val commutative = ()
+          val one = fromInt 0
+          
+          val EQ  = (op =)
+          val MUL = fn (x, y) => xorb (x, y)
+          val DIV = MUL
+          val INV = fn x => x
+        end
+      
+      structure Multiplication =
+        struct
+          type t = word
+          val order = FINITE (Int.toLarge size)
+          
+          val associative = ()
+          val commutative = ()
+          val one = fromInt 1
+          
+          val EQ  = (op =)
+          val MUL = fn (x, y) =>
+            if x = zero orelse y = zero then zero else
+            let val (lx, ly) = (log x, log y)
+            in exp (lx + ly) end
+          val DIV = fn (x, y) =>
+            let val (lx, ly) = (log x, log y)
+            in exp (lx + msize - ly) end
+          val INV = fn x => 
+            let val lx = log x
+            in exp (msize - lx) end
+        end
+      
+      val distributive = ()
+      val no_zero_divisors = ()
+    end
+ end

Added: mltonlib/trunk/ca/terpstra/math/galois.sml
===================================================================
--- mltonlib/trunk/ca/terpstra/math/galois.sml	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/galois.sml	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,21 @@
+local
+  structure P4 = 
+    struct 
+      structure W = Word4
+      val base : W.word = 0wx3 
+    end
+  structure P5 =
+    struct
+      structure W = Word5
+      val base : W.word = 0wx9
+    end
+  structure P8 = 
+    struct 
+      structure W = Word8 
+      val base : W.word = 0wx1B
+    end
+in
+  structure Galois4 = GaloisFromTable(P4)
+  structure Galois5 = GaloisFromTable(P5)
+  structure Galois8 = GaloisFromTable(P8)
+end

Added: mltonlib/trunk/ca/terpstra/math/gcd.fun
===================================================================
--- mltonlib/trunk/ca/terpstra/math/gcd.fun	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/gcd.fun	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,49 @@
+exception NoSolution
+
+functor GCD(E : EUCLIDEAN_DOMAIN) =
+  struct
+    local
+      structure B = EuclideanDomainPercent(E)
+      open B
+    in
+      (* (g, i, j, x)  = egcd(a, b)
+       * gcd(a,b) = g = a*i + b*j
+       * x = -1 ->  i <= 0 and j >= 0
+       * x = +1 ->  j <= 0 and i >= 0
+       *)
+      fun egcd (a, b) =
+        if (b =% #%0) then (a, #%1, #%0, #%1) else
+        let
+          val (q, r)       = a //% b
+          val (g, i, j, x) = egcd (b, r)
+          in
+          (g, j, i -% q*%j, ~%x)
+        end
+      
+      fun gcd (a, b) = case egcd (a, b) of (g, _, _, _) => g
+      fun lcm (a, b) = a*%b /% gcd(a, b)
+      
+      fun gcdinv (n, m) =
+        let
+          val (g, ni, mi, x) = egcd(n, m)
+        in
+          if x =% #%1 
+          then (g, ni, n+%mi)
+          else (g, m+%ni, mi)
+        end
+    
+    fun inv (a, n) = case gcdinv (n, a) of (_, _, ai) => ai
+    
+    fun crt nil = (#%0, #%1)
+      | crt ((a, n) :: x) =
+        let
+          val (b, m) = crt x
+          val (g, ni, mi) = gcdinv (n, m)
+          val l = n*%m/%g
+        in
+          if a %% g =% b %% g
+          then ((a*%m*%mi +% b*%n*%ni)/%g %% l, l)
+          else raise NoSolution
+        end
+    end
+  end

Added: mltonlib/trunk/ca/terpstra/math/groups.fun
===================================================================
--- mltonlib/trunk/ca/terpstra/math/groups.fun	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/groups.fun	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,149 @@
+(****************************************************************** Group ops *)
+
+exception ImpossibleConstant
+
+functor SetPercent(S : BINARY_OPERATION) =
+  struct
+    val (op =% ) = S.EQ
+    val (op !=%) = not o S.EQ
+  end
+
+functor SetDollar(S : BINARY_OPERATION) =
+  struct
+    val (op =$ ) = S.EQ
+    val (op !=$) = not o S.EQ
+  end
+
+functor BinaryOperationMulPercent(B : BINARY_OPERATION) =
+  struct
+    local structure S = SetPercent(B) in open S end
+    val (op *% )  = B.MUL
+    local open LargeInt in
+      fun _ **% 0 = raise ImpossibleConstant
+        | x **% 1 = x
+        | x **% e = 
+          let val h = x **% (e div 2) 
+          in if (e mod 2) = 0 then h *% h else h *% h *% x end
+    end
+  end
+functor BinaryOperationAddPercent(B : BINARY_OPERATION) =
+  struct
+    local structure S = SetPercent(B) in open S end
+    val (op +% )  = B.MUL
+    local open LargeInt in
+      fun _ ++% 0 = raise ImpossibleConstant
+        | x ++% 1 = x
+        | x ++% e = 
+          let val h = x ++% (e div 2) 
+          in if (e mod 2) = 0 then h +% h else h +% h +% x end
+    end
+  end
+
+functor BinaryOperationMulDollar(B : BINARY_OPERATION) =
+  struct
+    local structure S = SetDollar(B) in open S end
+    val (op *$ ) = B.MUL
+    local open LargeInt in
+      fun _ **$ 0 = raise ImpossibleConstant
+        | x **$ 1 = x
+        | x **$ e = 
+          let val h = x **$ (e div 2) 
+          in if (e mod 2) = 0 then h *$ h else h *$ h *$ x end
+    end
+  end
+functor BinaryOperationAddDollar(B : BINARY_OPERATION) =
+  struct
+    local structure S = SetDollar(B) in open S end
+    val (op +$ ) = B.MUL
+    local open LargeInt in
+      fun _ ++$ 0 = raise ImpossibleConstant
+        | x ++$ 1 = x
+        | x ++$ e = 
+          let val h = x ++$ (e div 2) 
+          in if (e mod 2) = 0 then h +$ h else h +$ h +$ x end
+    end
+  end
+
+functor SemiGroupMulPercent(S : SEMIGROUP) = BinaryOperationMulPercent(S)
+functor SemiGroupAddPercent(S : SEMIGROUP) = BinaryOperationAddPercent(S)
+functor SemiGroupMulDollar (S : SEMIGROUP) = BinaryOperationMulDollar (S)
+functor SemiGroupAddDollar (S : SEMIGROUP) = BinaryOperationAddDollar (S)
+
+functor MonoidMulPercent(M : MONOID) = 
+  struct
+    local structure S = SemiGroupMulPercent(M) in open S end
+    val (op **%) = fn (_, 0) => M.one | (x, e) => x **% e
+    val #% = fn 1 => M.one | _ => raise ImpossibleConstant
+  end
+functor MonoidAddPercent(M : MONOID) = 
+  struct
+    local structure S = SemiGroupAddPercent(M) in open S end    
+    val (op ++%) = fn (_, 0) => M.one | (x, e) => x ++% e
+    val #% = fn 0 => M.one | _ => raise ImpossibleConstant
+  end
+
+functor MonoidMulDollar(M : MONOID) = 
+  struct
+    local structure S = SemiGroupMulDollar(M) in open S end
+    val (op **$) = fn (_, 0) => M.one | (x, e) => x **$ e
+    val #$ = fn 1 => M.one | _ => raise ImpossibleConstant
+  end
+functor MonoidAddDollar(M : MONOID) = 
+  struct
+    local structure S = SemiGroupAddDollar(M) in open S end
+    val (op ++$) = fn (_, 0) => M.one | (x, e) => x ++$ e
+    val #$ = fn 0 => M.one | _ => raise ImpossibleConstant
+  end
+
+functor AbelianMonoidMulPercent(A : ABELIAN_MONOID) = MonoidMulPercent(A)
+functor AbelianMonoidAddPercent(A : ABELIAN_MONOID) = MonoidAddPercent(A)
+functor AbelianMonoidMulDollar (A : ABELIAN_MONOID) = MonoidMulDollar (A)
+functor AbelianMonoidAddDollar (A : ABELIAN_MONOID) = MonoidAddDollar (A)
+
+functor GroupMulPercent(G : GROUP) =
+  struct
+    local structure S = MonoidMulPercent(G) in open S end
+    val (op !% ) = G.INV
+    val (op **%) = fn (x, e) => if e < 0 then !%x **% ~e else x **% e
+  end
+functor GroupAddPercent(G : GROUP) =
+  struct
+    local structure S = MonoidAddPercent(G) in open S end
+    val (op ~% ) = G.INV
+    val (op ++%) = fn (x, e) => if e < 0 then ~%x ++% ~e else x ++% e
+  end
+
+functor GroupMulDollar(G : GROUP) =
+  struct
+    local structure S = MonoidMulDollar(G) in open S end
+    val (op !$ ) = G.INV
+    val (op **$) = fn (x, e) => if e < 0 then !$x **$ ~e else x **$ e
+  end
+functor GroupAddDollar(G : GROUP) =
+  struct
+    local structure S = MonoidAddDollar(G) in open S end
+    val (op ~$ ) = G.INV
+    val (op ++$) = fn (x, e) => if e < 0 then ~$x ++$ ~e else x ++$ e
+  end
+
+functor AbelianGroupMulPercent(A : ABELIAN_GROUP) = 
+  struct
+    local structure S = GroupMulPercent(A) in open S end
+    val (op /%) = A.DIV
+  end
+functor AbelianGroupAddPercent(A : ABELIAN_GROUP) = 
+  struct
+    local structure S = GroupAddPercent(A) in open S end
+    val (op -%) = A.DIV
+  end
+
+functor AbelianGroupMulDollar(A : ABELIAN_GROUP) = 
+  struct
+    local structure S = GroupMulDollar(A) in open S end
+    val (op /$) = A.DIV
+  end
+functor AbelianGroupAddDollar(A : ABELIAN_GROUP) = 
+  struct
+    local structure S = GroupAddDollar(A) in open S end
+    val (op -$) = A.DIV
+  end

Added: mltonlib/trunk/ca/terpstra/math/groups.sig
===================================================================
--- mltonlib/trunk/ca/terpstra/math/groups.sig	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/groups.sig	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,65 @@
+signature SEMIGROUP =
+  sig
+    include BINARY_OPERATION
+    (* a*(b*c) = (a*b)*c *)
+    val associative : unit 
+  end
+
+signature MONOID =
+  sig
+    include SEMIGROUP
+    
+    (* one*x = x*one = x *)
+    val one : t
+  end
+
+signature ABELIAN_MONOID =
+  sig
+    include MONOID
+    
+    (* a*b = b*a *)
+    val commutative : unit
+  end
+
+signature GROUP =
+  sig
+    include MONOID
+    (* y * (y^-1) = (y^-1) * y = one *)
+    val INV : t -> t
+  end
+
+signature PERMUTATION =
+  sig
+    include GROUP
+    (* include ENDOFUNCTION *)
+    type v
+    val EVAL: t -> v -> v
+  end
+signature AUTOFUNCTION = PERMUTATION
+
+signature ABELIAN_GROUP =
+  sig
+    include GROUP
+    
+    (* a*b = b*a *)
+    val commutative : unit
+    
+    (* x/y = x*(y^-1)) -- could be defined in GROUP, but is confusing *)
+    val DIV : (t * t) -> t
+  end
+
+signature CYCLIC_GROUP =
+  sig
+    include ABELIAN_GROUP
+    (* x = g^i *)
+    val generator : t
+  end
+
+(****************************************************************** Unity *)
+
+signature FINITE_SUBGROUPS =
+  sig
+    type t
+    (* !!! Somehow figure out how to grab unity roots *)
+  end
+

Added: mltonlib/trunk/ca/terpstra/math/log.fun
===================================================================
--- mltonlib/trunk/ca/terpstra/math/log.fun	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/log.fun	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,28 @@
+(*
+functor DiscreteLogarithm(G : GROUP) =
+  struct
+    local
+      structure B = GroupMulPercent(G)
+      structure D = GCD(Z)
+      open B D Factor LargeInt
+      
+      exception NotDiscrete
+      val order =
+        case G.order of
+          FINITE x => x
+        | _ => raise NotDiscrete
+        
+      datatype Factorization =
+          PRIME of LargeInt.int
+        | POWER of Order * LargeInt.int
+        | COPRIME of Order * Order
+      withtype Order = LargeInt.int * Factorization
+      
+      val factors = factor order
+      
+      fun log (n, f)
+    in
+      fun log = crtLog
+    end
+  end
+*)

Added: mltonlib/trunk/ca/terpstra/math/math.mlb
===================================================================
--- mltonlib/trunk/ca/terpstra/math/math.mlb	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/math.mlb	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,44 @@
+ann
+  "deadCode true"
+  "sequenceNonUnit warn"
+in
+  local
+    $(MLTON_ROOT)/basis/mlton.mlb
+    $(MLTON_ROOT)/basis/basis.mlb
+  in
+    (* base types *)
+    ops.sig
+    ops.sml
+    groups.sig
+    groups.fun
+    rings.sig
+    rings.fun
+    algebra.sig
+    algebra.fun
+    
+    polynomial.fun
+    
+    (* generic algorithms need for construction *)
+    gcd.fun
+    
+    (* concrete constructions *)
+    order.sml
+    z.fun
+    z.sml
+    r.fun
+    r.sml
+    c.fun
+    c.sml
+    q.fun
+    q.sml
+    mersenne.fun
+    mersenne.sml
+    galois.fun
+    galois.sml
+    permutation.sml
+    
+    (* other algorithms *)
+    factor.sml
+    log.fun
+  end
+end

Added: mltonlib/trunk/ca/terpstra/math/mersenne.fun
===================================================================
--- mltonlib/trunk/ca/terpstra/math/mersenne.fun	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/mersenne.fun	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,77 @@
+signature MERSENNE_BASE =
+  sig
+    structure Z  : WORD (* fits the numbers with 1 bit to spare *)
+    structure ZZ : WORD (* fits the product *)
+    val bits : word
+  end
+
+exception MersenneOverflow
+
+functor Mersenne(M : MERSENNE_BASE) : FIELD =
+  struct
+    local
+      structure Z = M.Z
+      structure ZZ = M.ZZ
+      structure O = EuclideanDomainDollar(Order)
+      structure G = GCD(EuclideanDomainOfWord(Z))
+      open Z
+      open O
+      open G
+      
+      val mbits = M.bits
+      val mmbits = Word.+ (mbits, mbits)
+      val rbits = Word.fromInt wordSize
+      val rrbits = Word.fromInt ZZ.wordSize
+      val rbitsm1 = Word.- (rbits, 0w1)
+      
+      val _ = if Word.>= ( mbits,  rbits) then raise MersenneOverflow else ()
+      val _ = if Word.>= (mmbits, rrbits) then raise MersenneOverflow else ()
+      
+      val mmask = << (fromInt 1, mbits) - fromInt 1
+    in
+      type t = word
+      val characteristic = toLargeInt mmask
+      
+      structure Addition =
+        struct
+          type t = word
+          val order = FINITE characteristic
+          
+          val associative = ()
+          val commutative = ()
+          val one = fromInt 0
+          
+          val EQ  = (op =)
+          val MUL = fn (x, y) => 
+            let val z = x + y in andb (z, mmask) + >> (z, mbits) end
+          val DIV = fn (x, y) =>
+            let val z = x - y in andb (z, mmask) - >> (z, rbitsm1) end
+          val INV = fn x => mmask - x
+        end
+      
+      structure Multiplication =
+        struct
+          type t = word
+          val order = Addition.order -$ #$1
+          
+          val associative = ()
+          val commutative = ()
+          val one = fromInt 1
+          
+          val EQ  = (op =)
+          val MUL = fn (x, y) =>
+            let
+              val ZZ = ZZ.fromLarge o toLarge
+              val Z = fromLarge o ZZ.toLarge
+              val z = ZZ.* (ZZ x, ZZ y)
+            in
+              Addition.MUL (Z (ZZ.>> (z, mbits)), andb (Z z, mmask))
+            end
+          val INV = fn x => inv (x, mmask)
+          val DIV = fn (x, y) => MUL (x, INV y)
+        end
+      
+      val distributive = ()
+      val no_zero_divisors = ()
+    end
+ end

Added: mltonlib/trunk/ca/terpstra/math/mersenne.sml
===================================================================
--- mltonlib/trunk/ca/terpstra/math/mersenne.sml	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/mersenne.sml	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,27 @@
+(* all Mersenne primes up to 64 bits: 2, 3, 5, 7, 13, 17, 19, 31, 61 *)
+(* In order to use 61 we need a Word128 on 64bit machines *)
+
+local
+  structure P7 =
+    struct
+      structure Z = Word8
+      structure ZZ = Word16
+      val bits = 0w7
+    end
+  structure P13 =
+    struct
+      structure Z = Word16
+      structure ZZ = Word32
+      val bits = 0w13
+    end
+  structure P31 =
+    struct
+      structure Z = Word32
+      structure ZZ = Word64
+      val bits = 0w31
+    end
+in
+  structure Mersenne7  = Mersenne(P7)
+  structure Mersenne13 = Mersenne(P13)
+  structure Mersenne31 = Mersenne(P31)
+end

Added: mltonlib/trunk/ca/terpstra/math/ops.sig
===================================================================
--- mltonlib/trunk/ca/terpstra/math/ops.sig	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/ops.sig	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,23 @@
+(****************************************************************** Groups *)
+
+datatype order = FINITE of LargeInt.int | COUNTABLE | UNCOUNTABLE
+
+signature SET =
+  sig
+    type t
+    val order: order
+    val EQ: (t * t) -> bool
+  end
+
+signature BINARY_OPERATION =
+  sig
+    include SET
+    val MUL: (t * t) -> t
+  end
+
+signature ENDOFUNCTION =
+  sig
+    include BINARY_OPERATION
+    type v
+    val EVAL: t -> v -> v
+  end

Added: mltonlib/trunk/ca/terpstra/math/ops.sml
===================================================================
--- mltonlib/trunk/ca/terpstra/math/ops.sml	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/ops.sml	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,16 @@
+(****************************************************************** Operators *)
+
+infix 8 ++% **%      (* additive and multiplicative exponentiation *)
+infix 7 *% /% %% //% (*  //% = (/%, %%) = (div, mod) *)
+infix 6 +% -%
+infix 4 =% !=% <%    (* <>% would imply <% which does not always exist *)
+nonfix ~% !% #%
+
+(* the operators in an algebra are always these (above for scalars) *)
+infix 8 ++$ **$
+infix 7 *$ /$ %$ //$
+infix 6 +$ -$
+infix 4 =$ !=$ <$
+nonfix ~$ !$ #$
+
+infix 7 *& (* for scalar operations with a vector *)

Added: mltonlib/trunk/ca/terpstra/math/order.sml
===================================================================
--- mltonlib/trunk/ca/terpstra/math/order.sml	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/order.sml	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,59 @@
+structure Order : EUCLIDEAN_DOMAIN =
+  struct
+    local
+      exception Undefined
+      open LargeInt
+    in
+      type t = order
+      val characteristic = LargeInt.fromInt 0
+      
+      structure Addition = 
+        struct
+          type t = order
+          val order = UNCOUNTABLE
+          
+          val associative = ()
+          val commutative = ()
+          val one = FINITE 0
+          
+          val EQ = (op =)
+          fun MUL (FINITE x, FINITE y) = FINITE (x+y)
+            | MUL (UNCOUNTABLE, _) = UNCOUNTABLE
+            | MUL (_, UNCOUNTABLE) = UNCOUNTABLE
+            | MUL _ = COUNTABLE
+          fun INV (FINITE x) = FINITE (~x)
+            | INV _ = raise Undefined
+          fun DIV (x, y) = MUL (x, INV y)
+        end
+      
+      structure Multiplication = 
+        struct
+          type t = order
+          val order = UNCOUNTABLE
+          
+          val associative = ()
+          val commutative = ()
+          val one = FINITE 1
+          
+          val EQ = (op =)
+          fun MUL (FINITE x, FINITE y) = FINITE (x*y)
+            | MUL (_, FINITE 0) = raise Undefined
+            | MUL (FINITE 0, _) = raise Undefined
+            | MUL (UNCOUNTABLE, _) = UNCOUNTABLE
+            | MUL (_, UNCOUNTABLE) = UNCOUNTABLE
+            | MUL _ = COUNTABLE
+        end
+      
+      val distributive = ()
+      val no_zero_divisors = ()
+      
+      fun QUO (FINITE a, FINITE b) = (FINITE (a div b), FINITE (a mod b))
+        | QUO _ = raise Undefined
+      
+      fun LT (UNCOUNTABLE, _) = false
+        | LT (_, UNCOUNTABLE) = true
+        | LT (COUNTABLE, _)   = false
+        | LT (_, COUNTABLE)   = true
+        | LT (FINITE x, FINITE y) = x < y
+    end
+  end

Added: mltonlib/trunk/ca/terpstra/math/permutation.sml
===================================================================
--- mltonlib/trunk/ca/terpstra/math/permutation.sml	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/permutation.sml	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,210 @@
+signature FINITE_PERMUTATION =
+  sig
+    include PERMUTATION
+    
+    (* a bijection exists between naturals and permutations *)
+    val toInt:  t -> int
+    val fromInt: int -> t
+    val toLargeInt: t -> LargeInt.int
+    val fromLargeInt: LargeInt.int -> t
+    
+    (* an alternate representation exists as cycles *)
+    val fromCycle: int list -> t
+    val fromCycles: int list list -> t
+    val toCycles: t -> int list list
+  end
+
+structure FinitePermutation : FINITE_PERMUTATION =
+  struct
+    type v = int
+    type t = int Vector.vector
+    val order = COUNTABLE
+    
+    val associative = ()
+    val one = Vector.tabulate (0, fn _ => 0)
+    
+    fun EVAL f x =
+      if x >= Vector.length f then x else
+      Vector.sub (f, x)
+    
+    fun EQ (x, y) = 
+      let
+        val lx = Vector.length x
+        val ly = Vector.length y
+      in
+        if lx < ly 
+        then Vector.foldli (fn (i, v, a) => a andalso v = EVAL x i) true y
+        else Vector.foldli (fn (i, v, a) => a andalso v = EVAL y i) true x
+      end
+    
+    fun MUL (x, y) =
+      let
+        val lx = Vector.length x
+        val ly = Vector.length y
+        val l = if lx < ly then ly else lx
+      in
+        Vector.tabulate (l, fn i => EVAL x (EVAL y i))
+      end
+    
+    fun INV x = 
+      let
+        val y = Array.array (Vector.length x, 0)
+      in
+        Vector.appi (fn (i, v) => Array.update (y, v, i)) x;
+        Array.vector y
+      end
+    
+    fun toInt p =
+      let
+        fun helper p =
+          let
+            val l = Vector.length p
+          in
+            if l < 2 then (1, 0) else
+            let
+              val i = l - 1
+              val s = VectorSlice.slice (p, 0, SOME i)
+              val x = Vector.sub (p, i)
+              val v = VectorSlice.map (fn y => if y > x then y-1 else y) s
+              val (fact, out) = helper v
+            in
+              (fact * l, out + (i - x) * fact)
+            end
+          end
+      in
+        #2 (helper p)
+      end
+    
+    fun toLargeInt p =
+      let
+        fun helper p =
+          let
+            val l = Vector.length p
+          in
+            if l < 2 then (1, 0) else
+            let
+              val i = l - 1
+              val s = VectorSlice.slice (p, 0, SOME i)
+              val x = Vector.sub (p, i)
+              val v = VectorSlice.map (fn y => if y > x then y-1 else y) s
+              val (fact, out) = helper v
+              val y = i - x
+              open LargeInt
+            in
+              (fact * fromInt l, out + fromInt y * fact)
+            end
+          end
+      in
+        #2 (helper p)
+      end
+    
+    fun fromInt x =
+      if x = 0 then Vector.tabulate (0, fn _ => 0) else
+      let
+        fun grow (l, f) =
+          if f > x then (l, f) else
+          grow (l+1, f*(l+1))
+        val (l, f) = grow (0, 1)
+        fun helper (1, _, _) = Vector.tabulate (1, fn _ => 0)
+          | helper (l, f, x) =
+          let
+            val (l1, f) = (l - 1, f div l)
+            val (q, r) = (x div f, x mod f)
+            val p = helper (l1, f, r)
+            val z = (l1 - q)
+            fun build i = 
+              if i = l1 then z else
+              let val y = Vector.sub (p, i) in
+              if y >= z then y+1 else y end
+          in
+            Vector.tabulate (l, build)
+          end
+      in
+        helper (l, f, x)
+      end
+    
+    fun fromLargeInt x =
+      if x = 0 then Vector.tabulate (0, fn _ => 0) else
+      let
+        fun grow (l, f) =
+          if f > x then (l, f) else
+          grow (l + 1, LargeInt.* (f, LargeInt.fromInt (l + 1)))
+        val (l, f) = grow (0, 1)
+        fun helper (1, _, _) = Vector.tabulate (1, fn _ => 0)
+          | helper (l, f, x) =
+          let
+            val (l1, f) = (l - 1, LargeInt.div (f, LargeInt.fromInt l))
+            val (q, r) = IntInf.quotRem (x, f)
+            val p = helper (l1, f, r)
+            val z = (l1 - LargeInt.toInt q)
+            fun build i = 
+              if i = l1 then z else
+              let val y = Vector.sub (p, i) in
+              if y >= z then y+1 else y end
+          in
+            Vector.tabulate (l, build)
+          end
+      in
+        helper (l, f, x)
+      end
+    
+    fun fromCycle c =
+      let
+        val m = List.foldl (fn (x, a) => if x < a then a else x) 0 c
+        val a = Array.tabulate (m+1, fn i => i)
+        fun helper [] = ()
+          | helper (x :: []) = Array.update (a, x, List.hd c)
+          | helper (x :: y :: r) = (
+          Array.update (a, x, y);
+          helper (y :: r))
+      in
+        helper c;
+        Array.vector a
+      end
+    
+    fun fromCycles l =
+      List.foldl (fn (x, a) => MUL (fromCycle x, a)) one l
+    
+    fun toCycles p =
+      let
+        val a = Array.tabulate (Vector.length p, fn i => false)
+        fun trace i =
+          if Array.sub (a, i) then [] else
+          (Array.update (a, i, true);
+           i :: trace (Vector.sub (p, i)))
+        fun scan (i, l) =
+          if i = l then [] else
+          case trace i of 
+              [] => scan (i+1, l)
+            | _ :: [] => scan (i+1, l)
+            | x => x :: scan (i+1, l)
+      in
+        scan (0, Vector.length p)
+      end
+  end
+
+(*
+fun test (x, e) =
+  if x = e then () else
+  let
+    val p = FinitePermutation.fromLargeInt (LargeInt.fromInt x)
+    val y = FinitePermutation.toLargeInt p
+  in
+    print (LargeInt.toString y ^ ":");
+    Vector.app (fn y => print (" " ^ Int.toString y)) p;
+    print "\n";
+    test (x+1, e)
+  end
+
+val () = test (0, 720)
+
+val p = FinitePermutation.fromCycles [[5, 4], [3], [], [2, 6, 3]]
+val () = Vector.app (fn y => print (" " ^ Int.toString y)) p
+val () = print "\n"
+
+val p = FinitePermutation.fromCycles [[5, 4], [3], [], [2, 6, 3]]
+val cs = FinitePermutation.toCycles p
+val pc = List.app (fn y => print (" " ^ Int.toString y))
+val pcs = List.app (fn y => (pc y; print "\n"))
+val () = pcs cs
+*)

Added: mltonlib/trunk/ca/terpstra/math/polynomial.fun
===================================================================
--- mltonlib/trunk/ca/terpstra/math/polynomial.fun	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/polynomial.fun	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,311 @@
+signature POLYNOMIAL =
+  sig 
+    include EUCLIDEAN_DOMAIN
+    (* include UNITARY_ASSOCIATIVE_FIELD_ALGEBRA: *)
+    type e 
+    structure Base : FIELD where type t = e
+    structure ScalarMultiplication : SCALAR_MULTIPLY where type e = e and type t = t
+    val bilinear : unit
+    
+    val fromList: e list -> t
+    val eval: t -> e -> e
+    val primitive: t -> bool
+  end
+
+functor PolynomialOverField(F : FIELD) : POLYNOMIAL =
+  struct
+    local
+      structure B = FieldPercent(F)
+      structure V = Vector
+      open B
+      open V
+      open VectorSlice
+      
+      val zero = #%0
+      val one = #%1
+      
+      fun constant c = full (tabulate (1, fn _ => c))
+      fun trim p n = subslice (p, 0, if n < length p then SOME n else NONE)
+      fun smul (x, y) = map (fn a => x *% a) y
+      
+      (* reverse the polnomial's coeffs; p(1/x)*x^deg(p) *)
+      fun rev p = 
+        let
+          val b = length p - 1
+        in
+          full (tabulate (length p, fn i => sub (p, b - i)))
+        end
+      
+      fun normalize p =
+        let
+          val (v, s, l) = base p
+          fun lastzero i =
+            if i = s then 0 else
+            let 
+              val i1 = i - 1 
+            in
+              if V.sub (v, i1) =% zero then lastzero i1 else i-s
+            end
+        in
+          subslice (p, 0, SOME (lastzero (s+l)))
+        end
+      
+      fun padd (x, y) =
+        let
+          val (v1, v2) = 
+            if length x < length y then (x, y) else (y, x)
+          val len1 = length v1 (* shorter length *)
+          val len2 = length v2
+          fun add i =
+            if i < len1
+            then sub (v1, i) +% sub (v2, i)
+            else sub (v2, i)
+        in
+          full (tabulate (len2, add))
+        end
+      
+      fun psub (x, y) =
+        let
+          val tab =
+            if length x < length y
+            then (length y,
+              let 
+                val len = length x
+              in
+                fn i =>
+                  if i < len
+                  then sub (x, i) -% sub (y, i)
+                  else ~% (sub (y, i))
+              end)
+            else (length x,
+              let
+                val len = length y
+              in
+                fn i =>
+                  if i < len
+                  then sub (x, i) -% sub (y, i)
+                  else sub (x, i)
+              end)
+        in
+          full (tabulate tab)
+        end
+      
+      (* long multiplication *)
+      fun long (x, y) = (* length x < length y *)
+        if length x = 1 then smul (sub (x, 0), y) else
+        let
+          val l = smul (sub (x, 0), y)
+          val hx = subslice (x, 1, NONE)
+          val h = long (hx, y)
+          fun join i = 
+            if i = 0 then V.sub (l, 0) else
+            if i >= V.length l then V.sub (h, i-1) else
+            V.sub (l, i) +% V.sub (h, i-1)
+        in
+          tabulate (length x + length y - 1, join)
+        end
+        
+      (* karatsuba's trick *)
+      fun kara (x, y) = (* length x < length y *)
+        let val (lx, ly) = (length x, length y) (* example: 5, 8 *) in
+        if lx < 5 then long (x, y) else
+        (* (a*x+b)*(c*x+d) = a*c*x + (a*d+b*c)*x + b*d 
+         * (a+b)*(c+d) = (a*c + (a*d + b*c) + b*d)
+         *)
+        let
+          (* lx2 <= rx <= ry *)
+          val lx2 = lx div 2                   (* example: 2 *)
+          val (rx, ry) = (lx - lx2, ly - lx2)  (* example: 3, 6 *)
+          val lxy = lx + ly - 1                (* example: 12 *)
+          val lxh = lx2 + lx2                  (* example: 4 *)
+          val lxf = lxh - 1                    (* example: 3 *)
+          val rxy = rx + ry - 1                (* example: 8 *)
+          val lx2r = lx2 + rxy                 (* example: 10 *)
+          
+          val a = subslice (x, lx2, NONE)      (* length = rx  (3) *)
+          val b = subslice (x, 0, SOME lx2)    (* length = lx2 (2) *)
+          val c = subslice (y, lx2, NONE)      (* length = ry  (6) *)
+          val d = subslice (y, 0, SOME lx2)    (* length = lx2 (2) *)
+          
+          val ab = padd (a, b)                 (* length = rx  (3) *)
+          val cd = padd (c, d)                 (* length = ry  (6) *)
+          val abcd = kara (ab, cd)             (* length = rxy (8) *)
+          val ac = kara (a, c)                 (* length = rxy (8) *)
+          val bd = kara (b, d)                 (* length = lxf (3) *)
+          
+          val (adbc, _, _) = 
+            base (psub(
+              full abcd, padd(full ac, full bd)))
+          
+          (*         v-- lxh
+           *  ---ac---
+           *   ^--adbc--
+           *   |      ^bd-
+           *   |      |^ 0
+           *   |      |lx2
+           *   lx2r   lxf
+           *)
+          (*!!! all these tests are grossly inefficient *)
+          fun join i =
+            case Int.compare (i, lxf) of
+            LESS => if i < lx2 
+                then V.sub (bd, i)
+                else V.sub (adbc, i-lx2) +% V.sub (bd, i)
+            | EQUAL => V.sub (adbc, i-lx2)
+            | GREATER =>
+                if i < lx2r 
+                then V.sub (ac, i-lxh) +% V.sub (adbc, i-lx2)
+                else V.sub (ac, i-lxh)
+        in
+          V.tabulate (lxy, join)
+        end end
+      
+      (* !!! No FFT yet *)
+      fun pmul (x, y) = 
+        if length x < length y
+        then if length x = 0 then x else full (kara (x, y))
+        else if length y = 0 then y else full (kara (y, x))
+      
+      (* !!! write an inner product method *)
+      
+      (* !!! don't be stupid; actually use the shortcut *)
+      fun pmuls (x, y, l) =
+        let
+          val xs = trim x l
+          val ys = trim y l
+          val z = pmul (xs, ys)
+        in
+          trim z l
+        end
+      
+      (* p(x)*q(x) = 1 + r(x)*x^2^n
+       * => 2-p(x)*q(x) = 1 - r(x)*x^2^n
+       * => (2-p(x)*q(x))*p(x)*q(x) = 1 - r(x)^2*x^2^(n+1)
+       * => q' = (2-pq)q
+       *)
+      fun invmodn p n = 
+        let
+          val init = constant (!% (sub (p, 0)))
+          val two  = constant (#%2)
+          fun grow q =
+            if length q >= n then q else
+            let
+              val nl = length q + length q
+              val ps = trim p nl
+              val pq = pmul (q, ps) (* !!! we don't need high terms... *)
+              val neg = psub (two, pq)
+              (* !!! use inner product; we know low terms and don't need high *)
+              val nq = pmul (neg, q)
+            in
+              if length p = 1 then init else grow (trim nq nl)
+            end
+        in
+          trim (grow init) n
+        end
+    in
+      type e = F.t
+      type t = e slice
+      val characteristic = F.characteristic
+      
+      fun eval p x = foldr (fn (a, out) => out *% x +% a) zero p
+      val fromList = normalize o full o fromList
+      fun primitive p = sub (p, length p - 1) =% one
+      
+      structure Base = F
+      
+      structure Addition =
+        struct
+          type t = t
+          val order = case Base.Addition.order of 
+            UNCOUNTABLE => UNCOUNTABLE
+            | _ => COUNTABLE
+          
+          val associative = ()
+          val commutative = ()
+          val one = full (tabulate (0, fn _ => #%0))
+          
+          val EQ = fn (x, y) =>
+            let
+              val (v1, s1, l1) = base x
+              val (v2, s2, l2) = base y
+              val e1 = l1 + s1
+              fun compare (i1, i2) =
+                if i1 = e1 then true else
+                if V.sub (v1, i1) =% V.sub (v2, i2)
+                then compare (i1 + 1, i2 + 1)
+                else false
+            in
+              if l1 <> l2 then false else
+              compare (s1, s2)
+            end
+          
+          val MUL = normalize o padd
+          val DIV = normalize o psub
+          val INV = fn x => full (map (fn a => ~%a) x)
+        end
+      
+      structure Multiplication = 
+        struct
+          type t = t
+          val order = Addition.order
+          
+          val associative = ()
+          val commutative = ()
+          val one = full (tabulate (1, fn _ => #%1))
+          
+          val EQ = Addition.EQ
+          val MUL = normalize o pmul
+        end
+      
+      structure ScalarMultiplication =
+        struct
+          type e = e
+          type t = t
+          
+          val associative = ()
+          val distributive = ()
+          
+          val MUL = normalize o full o smul
+        end
+      
+      val QUO = fn (z, y) =>
+        let
+          (* q*y + r = z, where deg(r) < deg(y) and deg(q)+deg(y)=deg(z)
+           * => rev(q*y + r) = rev(z)
+           * => rev(q)rev(y) + rev(r)*x^(deg(z)-deg(r)) = rev(z)
+           * => rev(q)rev(y) = rev(z) mod x^(1+deg(z)-deg(y))
+           * => rev(q) = rev(z)/rev(y) mod x^(1+deg(q))
+           *)
+          val degz = length z - 1
+          val degy = length y - 1
+        in
+          if degz < degy then (Addition.one, z) else
+          let
+            val degq = degz - degy
+            val lenq = degq + 1
+            val ry = rev y
+            val iry = invmodn ry lenq
+            val rz = rev z
+            val rq = pmuls (rz, iry, lenq)
+            val q = rev rq
+            val qy = pmuls (q, y, degy)
+            val r = psub (trim z degy, qy)
+          in
+            (q, normalize r)
+          end
+        end
+      
+      fun LT (x, y) = length x < length y
+      
+      val distributive = ()
+      val no_zero_divisors = ()
+      val bilinear = ()
+    end
+  end
+
+functor Polynomial(P : POLYNOMIAL) =
+  struct
+    local structure S = FieldPercent(P.Base) in open S end
+    local structure S = EuclideanDomainDollar(P) in open S end
+    local structure S = ScalarMultiply(P.ScalarMultiplication) in open S end
+  end

Added: mltonlib/trunk/ca/terpstra/math/q.fun
===================================================================
--- mltonlib/trunk/ca/terpstra/math/q.fun	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/q.fun	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,97 @@
+functor QuotientOfIntegralDomain(I : INTEGRAL_DOMAIN) : FIELD =
+  struct
+    local
+      structure B = IntegralDomainPercent(I)
+      structure O = EuclideanDomainDollar(Order)
+      open B
+      open O
+    in
+      type t = I.t * I.t
+      val characteristic = I.characteristic
+      
+      structure Addition =
+        struct
+          type t = I.t * I.t
+          val order = COUNTABLE (* !!! no idea how to compute ... *)
+          
+          val associative = ()
+          val commutative = ()
+          val one = (#%0, #%1)
+          
+          val MUL = fn ((an, ad), (bn, bd)) => 
+            (an *% bd +% bn *% ad, ad *% bd)
+          val DIV = fn ((an, ad), (bn, bd)) =>
+            (an *% bd -% bn *% ad, ad *% bd)
+          val INV = fn (an, ad) => (~%an, ad)
+          
+          val EQ  = fn ((an, ad), (bn, bd)) => 
+            an *% bd =% bn *% ad
+        end
+        
+      structure Multiplication =
+        struct
+          type t = I.t * I.t
+          val order = COUNTABLE (* !!! no idea *)
+          
+          val associative = ()
+          val commutative = ()
+          val one = (#%1, #%1)
+          
+          val EQ = Addition.EQ
+          val MUL = fn ((an, ad), (bn, bd)) =>
+            (an *% bn, ad *% bd)
+          val INV = fn (an, ad) => (ad, an)
+          val DIV = fn (a, b) => MUL (a, INV b)
+        end
+      
+      val distributive = ()
+      val no_zero_divisors = ()
+    end
+  end
+
+functor QuotientOfEuclideanDomain(E : EUCLIDEAN_DOMAIN) : FIELD =
+  struct
+    local
+      structure B = EuclideanDomainPercent(E)
+      structure G = GCD(E)
+      structure Q = QuotientOfIntegralDomain(E)
+      open B
+      open G
+    in
+      type t = E.t * E.t
+      val characteristic = E.characteristic
+      
+      fun simplify (n, d) =
+        if d =% #%0 then Q.Addition.one else 
+        let
+          val g = gcd (n, d);
+        in
+          (n /% g, d /% g)
+        end
+      
+      structure Addition =
+        struct
+          open Q.Addition
+          
+          (* easier to compute *)
+          val EQ  = fn ((an, ad), (bn, bd)) => 
+            ((an =%   bn) andalso (ad =%   bd)) orelse
+            ((an =% ~%bn) andalso (ad =% ~%bd))
+            
+          val MUL = simplify o MUL
+          val DIV = simplify o DIV
+        end
+        
+      structure Multiplication =
+        struct
+          open Q.Multiplication
+          
+          val EQ = Addition.EQ
+          val MUL = simplify o MUL
+          val DIV = simplify o DIV
+        end
+      
+      val distributive = ()
+      val no_zero_divisors = ()
+    end
+  end

Added: mltonlib/trunk/ca/terpstra/math/q.sml
===================================================================
--- mltonlib/trunk/ca/terpstra/math/q.sml	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/q.sml	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,7 @@
+structure Q = QuotientOfEuclideanDomain(Z)
+
+(* these are vulnerable to overflow *)
+structure Q64 = QuotientOfEuclideanDomain(Z64)
+structure Q32 = QuotientOfEuclideanDomain(Z32)
+structure Q16 = QuotientOfEuclideanDomain(Z16)
+structure Q8  = QuotientOfEuclideanDomain(Z8)

Added: mltonlib/trunk/ca/terpstra/math/r.fun
===================================================================
--- mltonlib/trunk/ca/terpstra/math/r.fun	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/r.fun	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,38 @@
+functor FieldOfReal(Real : REAL) : FIELD =
+  struct
+    type t = Real.real
+    val characteristic = LargeInt.fromInt 0
+    
+    structure Addition = 
+      struct
+        type t = Real.real
+        val order = UNCOUNTABLE
+        
+        val associative = ()
+        val commutative = ()
+        val one = Real.fromInt 0
+        
+        val EQ  = Real.==
+        val MUL = Real.+
+        val DIV = Real.-
+        val INV = Real.~
+      end
+    
+    structure Multiplication =
+      struct
+        type t = Real.real
+        val order = UNCOUNTABLE
+        
+        val associative = ()
+        val commutative = ()
+        val one = Real.fromInt 1
+        
+        val EQ  = Real.==
+        val MUL = Real.*
+        val DIV = Real./
+        val INV = fn x => DIV (one, x)
+      end
+    
+    val distributive     = ()
+    val no_zero_divisors = ()
+  end

Added: mltonlib/trunk/ca/terpstra/math/r.sml
===================================================================
--- mltonlib/trunk/ca/terpstra/math/r.sml	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/r.sml	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,4 @@
+structure R = FieldOfReal(LargeReal)
+
+structure R32 = FieldOfReal(Real32)
+structure R64 = FieldOfReal(Real64)

Added: mltonlib/trunk/ca/terpstra/math/rings.fun
===================================================================
--- mltonlib/trunk/ca/terpstra/math/rings.fun	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/rings.fun	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,86 @@
+(****************************************************************** Ring ops *)
+
+functor NonAssociativeRingPercent(R : NON_ASSOCIATIVE_RING) =
+  struct
+    local structure S = BinaryOperationMulPercent(R.Multiplication) in open S end
+    local structure S = AbelianGroupAddPercent(R.Addition) in open S end
+  end
+functor NonAssociativeRingDollar(R : NON_ASSOCIATIVE_RING) =
+  struct
+    local structure S = BinaryOperationMulDollar(R.Multiplication) in open S end
+    local structure S = AbelianGroupAddDollar(R.Addition) in open S end
+  end
+
+functor RingPercent(R : RING) =
+  struct
+    local structure S = SemiGroupMulPercent(R.Multiplication) in open S end
+    local structure S = AbelianGroupAddPercent(R.Addition) in open S end
+  end
+functor RingDollar(R : RING) =
+  struct
+    local structure S = SemiGroupMulDollar(R.Multiplication) in open S end
+    local structure S = AbelianGroupAddDollar(R.Addition) in open S end
+  end
+
+functor UnitaryRingPercent(U : UNITARY_RING) =
+  struct
+    local structure S = MonoidMulPercent(U.Multiplication) in open S end
+    local structure S = AbelianGroupAddPercent(U.Addition) in open S end
+    val #% = fn e => U.Multiplication.one ++% e
+  end
+functor UnitaryRingDollar(U : UNITARY_RING) =
+  struct
+    local structure S = MonoidMulDollar(U.Multiplication) in open S end
+    local structure S = AbelianGroupAddDollar(U.Addition) in open S end
+    val #$ = fn e => U.Multiplication.one ++$ e
+  end
+
+functor CommutativeRingPercent(C : COMMUTATIVE_RING) = 
+  struct
+    local structure S = AbelianMonoidMulPercent(C.Multiplication) in open S end
+    local structure S = AbelianGroupAddPercent(C.Addition) in open S end
+    val #% = fn e => C.Multiplication.one ++% e
+  end
+functor CommutativeRingDollar(C : COMMUTATIVE_RING) =
+  struct
+    local structure S = AbelianMonoidMulDollar(C.Multiplication) in open S end
+    local structure S = AbelianGroupAddDollar(C.Addition) in open S end
+    val #$ = fn e => C.Multiplication.one ++$ e
+  end
+
+functor IntegralDomainPercent(I : INTEGRAL_DOMAIN) = CommutativeRingPercent(I)
+functor IntegralDomainDollar (I : INTEGRAL_DOMAIN) = CommutativeRingDollar (I)
+
+functor EuclideanDomainPercent(E : EUCLIDEAN_DOMAIN) =
+  struct
+    local structure S = AbelianMonoidMulPercent(E.Multiplication) in open S end
+    local structure S = AbelianGroupAddPercent(E.Addition) in open S end
+    val #% = fn e => E.Multiplication.one ++% e
+    val (op /%) = #1 o E.QUO
+    val (op %%) = #2 o E.QUO
+    val (op //%) = E.QUO
+    val (op <%) = E.LT
+  end
+functor EuclideanDomainDollar(E : EUCLIDEAN_DOMAIN) =
+  struct
+    local structure S = AbelianMonoidMulDollar(E.Multiplication) in open S end
+    local structure S = AbelianGroupAddDollar(E.Addition) in open S end
+    val #$ = fn e => E.Multiplication.one ++$ e
+    val (op /$) = #1 o E.QUO
+    val (op %$) = #2 o E.QUO
+    val (op //$) = E.QUO
+    val (op <$) = E.LT
+  end
+
+functor FieldPercent(F : FIELD) =
+  struct
+    local structure S = AbelianGroupMulPercent(F.Multiplication) in open S end
+    local structure S = AbelianGroupAddPercent(F.Addition) in open S end
+    val #% = fn e => F.Multiplication.one ++% e
+  end
+functor FieldDollar(F : FIELD) =
+  struct
+    local structure S = AbelianGroupMulDollar(F.Multiplication) in open S end
+    local structure S = AbelianGroupAddDollar(F.Addition) in open S end
+    val #$ = fn e => F.Multiplication.one ++$ e
+  end

Added: mltonlib/trunk/ca/terpstra/math/rings.sig
===================================================================
--- mltonlib/trunk/ca/terpstra/math/rings.sig	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/rings.sig	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,104 @@
+(****************************************************************** Internal *)
+
+signature NON_ASSOCIATIVE_RING_ =
+  sig
+    type t
+    (* a*(b+c) = a*b + a*c
+     * (b+c)*a = b*a + c*a
+     *)
+    val distributive : unit
+    
+    (* x++c = zero  [c=zero if no positive integer works] *)
+    val characteristic : LargeInt.int
+  end
+
+signature RING_ =
+  sig
+    include NON_ASSOCIATIVE_RING_
+  end
+
+signature UNITARY_RING_ =
+  sig
+    include RING_
+  end
+
+signature COMMUTATIVE_RING_ =
+  sig
+    include UNITARY_RING_
+  end
+
+signature INTEGRAL_DOMAIN_ =
+  sig
+    include COMMUTATIVE_RING_
+    (* a*b = 0 -> a = 0 or b = 0 *)
+    val no_zero_divisors : unit
+  end
+
+signature EUCLIDEAN_DOMAIN_ =
+  sig
+    include INTEGRAL_DOMAIN_
+    (* (a, b) -> (q, r) *)
+    val QUO: (t * t) -> (t * t)
+    (* There must exist a function, w (that need not be exposed) where:
+     * b != 0 -> w(ab) >= w(a) 
+     *           a = qb + r, r = 0 or w(r) < w(b)
+     *)
+    (* (a, b) -> w(a) < w(b) *)
+    val LT: t * t -> bool
+  end
+
+signature FIELD_ =
+  sig
+    include INTEGRAL_DOMAIN_
+  end
+
+(****************************************************************** Rings *)
+
+signature NON_ASSOCIATIVE_RING =
+  sig
+    include NON_ASSOCIATIVE_RING_
+    structure Addition : ABELIAN_GROUP where type t = t
+    structure Multiplication : BINARY_OPERATION where type t = t
+  end
+
+signature RING =
+  sig
+    include RING_
+    structure Addition : ABELIAN_GROUP where type t = t
+    structure Multiplication : SEMIGROUP where type t = t
+  end
+
+signature UNITARY_RING =
+  sig
+    include UNITARY_RING_
+    structure Addition : ABELIAN_GROUP where type t = t
+    structure Multiplication : MONOID where type t = t
+  end
+
+signature COMMUTATIVE_RING =
+  sig
+    include COMMUTATIVE_RING_
+    structure Addition : ABELIAN_GROUP where type t = t
+    structure Multiplication : ABELIAN_MONOID where type t = t
+  end
+
+signature INTEGRAL_DOMAIN =
+  sig
+    include INTEGRAL_DOMAIN_
+    structure Addition : ABELIAN_GROUP where type t = t
+    structure Multiplication : ABELIAN_MONOID where type t = t
+  end
+
+signature EUCLIDEAN_DOMAIN =
+  sig
+    include EUCLIDEAN_DOMAIN_
+    structure Addition : ABELIAN_GROUP where type t = t
+    structure Multiplication : ABELIAN_MONOID where type t = t
+  end
+
+signature FIELD =
+  sig
+    include FIELD_
+    structure Addition : ABELIAN_GROUP where type t = t
+    structure Multiplication : ABELIAN_GROUP where type t = t
+  end

Added: mltonlib/trunk/ca/terpstra/math/test/test.mlb
===================================================================
--- mltonlib/trunk/ca/terpstra/math/test/test.mlb	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/test/test.mlb	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,12 @@
+ann
+  "warnUnused true"
+  "warnMatch true"
+  "sequenceUnit true"
+in
+  local
+    $(MLTON_ROOT)/basis/basis.mlb
+    ../math.mlb
+  in
+    test.sml
+  end
+end

Added: mltonlib/trunk/ca/terpstra/math/test/test.sml
===================================================================
--- mltonlib/trunk/ca/terpstra/math/test/test.sml	2006-12-19 02:58:00 UTC (rev 4985)
+++ mltonlib/trunk/ca/terpstra/math/test/test.sml	2006-12-19 02:59:11 UTC (rev 4986)
@@ -0,0 +1,86 @@
+structure B = FieldDollar(Galois4)
+open B
+
+fun table 16 = print "\n"
+  | table y = (
+    print ("0x" ^ Word4.toString (!$ (Word4.fromInt y)) ^ ", "); 
+    table (y+1))
+
+val _ = table 0
+
+(*fun ps nil = print "\n"
+  | ps (x :: y) = (print x; print " "; ps y)
+
+fun default y = fn
+   SOME x => x
+ | NONE   => y
+
+(*
+val toString = LargeInt.toString
+val ofString = LargeInt.fromString
+
+val (d, e, f) = case CommandLine.arguments () of
+    a :: b :: c :: _ => (ofString a, ofString b, ofString c)
+  | a :: b :: _      => (ofString a, ofString b, NONE)
+  | a :: _           => (ofString a, NONE,       NONE)
+  | _                => (NONE,       NONE,       NONE)
+
+structure G = GCD(Z)
+structure B = EuclideanDomainDollar(Z)
+open B
+open G
+
+val a = default 4234235 d
+val b = default 32 e
+val c = default 3242 f
+val (g, i, j, _) = egcd (a, b)
+
+val _ = ps [ 
+  toString a, "*", toString i, "+", toString b, "*", toString j, 
+  "=", toString g ]
+val _ = ps [
+  toString a, "**", toString b, "=", toString (a **$ b), "=",
+  toString (a **$ b %$ c), "mod", toString c ]
+*)
+
+structure P = PolynomialOverField(Galois8)
+structure B = Polynomial(P)
+structure G = GCD(P)
+open B
+open G
+
+(* For Q
+fun toString p = (
+  VectorSlice.foldl
+    (fn ((x, y), a) => (a ^ " (" ^ LargeInt.toString x ^ ", " ^ LargeInt.toString y ^ ")")) "[" p
+  ^ " ]")
+*)
+
+fun toString p =
+  VectorSlice.foldl (fn (x, a) => (a ^ " " ^ Word8.toString x)) "[" p ^ " ]"
+
+(* for Q
+val x = P.fromList [ (4, 3), (7, 3), (2, 1), (7, 8), (9, 2) ]
+val y = P.fromList [ (2, 1), (5, 3), (7, 4) ]
+*)
+
+(* for Galois8 *)
+val x = P.fromList [ 0wx7A, 0wx2F, 0wx10, 0wx3D, 0wxF2, 0wx02, 0wxDA, 0wxE0 ]
+val y = P.fromList [ 0wx40, 0wx2F, 0wxA2, 0wx89, 0wx62 ]
+
+(* for R
+val x = P.fromList [ 6.0, 2.0, 1.0, 9.0, 2.0, 5.0, 7.0, 11.0 ]
+val y = P.fromList [ 4.0, 3.0, 5.0, 8.0, 2.0 ]
+*)
+
+val z = x *$ y
+val _ = ps [ toString x, "*", toString y, "=", toString z ]
+
+val (q, r) = x //$ y
+val _ = ps [ toString q, "*", toString y, "+", toString r, "=", toString (q*$y+$r) ]
+
+val (g, i, j, _) = egcd (x, y)
+val _ = ps [ 
+  toString x, "*", toString i, "



More information about the MLton-commit mailing list