b0VIM 7.0/Lkdchrisbladybank02.cs.st-andrews.ac.uk/scratch/chris/release/cabal/cash-0.1/src/Math/ComputerAlgebra/Cash.hsutf-8 3210#"! Utpw_xd>;adwkhDc  D > =     x e T < -  V , +  \ U T  p\GF\C<;G&%n54TS~XW<gf-- aux fcts---------------------------------------------------------------------------euler n = length (filter (relprime n) [1..(n-1)])euler :: Int -> Int-- main fct---------------------------------------------------------------------------sumEuler_seq = sum . map euler . enumFromTo (1::Int)sumEuler_seq :: Int -> IntfactAcc n acc = factAcc (n-1) (n*acc)factAcc 0 acc = accfactAcc :: Integer -> Integer -> Integerfact n = n*(fact (n-1))fact 0 = 1fact :: Integer -> Integer-- -- purely Haskell side code-------------------------------------------------------resultant p1OM_str p2OM_str = callSCSCP scscp_CS_Resultant ( map toOM [p1OM_str, p2OM_str] )mult p1 p2 = callSCSCP scscp_CS_KaratsubaStr_x [p1, p2]mkRand n = callSCSCP scscp_CS_RandomPolynomialAsString ( map toOM [n] )call2 name x y = fromOM (callSCSCP name [toOM x,toOM y]) CAName -> a -> b -> ccall2 :: (OMData a, OMData b, OMData c) =>call1 name x = fromOM (callSCSCP name [toOM x]) CAName -> a -> bcall1 :: (OMData a, OMData b) => (callSCSCP name [])call0 name = unsafePerformIO (putStrLn $ "call0 of "++(show name)) `seq` call0 :: CAName -> OMObj -- Util fcts (from ParSCSCP.hs)-------------------------------------------------------ngoq = initServer (server "localhost" (Just 12321))#endif doClient portNum else fromInteger (read (head args)) then 12321 let portNum = if null args args <- getArgsmain = domain :: IO()#if 0-- boilerplate setup, including pre-shared info-- import Karatsuba -- import TestPolys-- import Poly#endifimport Eden-- import FoldDM-- import EdenHelpers -- helper functions#ifdef __PARALLEL_HASKELL__ import Math.ComputerAlgebra.Cash.BaseServices-- These are services, known to the client from the start#endifimport Math.ComputerAlgebra.Cash.CA_Skeletons-- abstractions over patterns of parallel coordination#ifdef HAVE_SKELETONS-- import SCSCP_Ex -- cut down version of SCSCP_Examples-- examples how to use itimport Math.ComputerAlgebra.Cash.HS2SCSCPimport Math.ComputerAlgebra.Cash.HS_SCSCPimport Math.ComputerAlgebra.Cash.SCSCP_APIimport Math.ComputerAlgebra.Cash.SGPTypesimport qualified Control.Exception as Cimport Control.Concurrentimport Control.Monad-- import Timeimport System.IO.Unsafeimport System.IOimport System.Exitimport Systemimport Networkimport List (delete)#undef RUN_SUMEULER_PAR #undef RUN_SUMEULER #undef RUN_POLYS #undef RUN_BUILTINS#undef GAP_SERVERimport Math.ComputerAlgebra.Cash.Datewhere ,toOMList, fromOMList, a_sparse_9, b_sparse_9, polyFromString, bagInter, myGcd) ,sumEulerListSCSCP, sumEulerFromToWithSCSCP, doClient, toOMMatrixmodule Math.ComputerAlgebra.Cash (server, initServer, call0, call1, call2, mkRand, mult, resultant, sumEuler_seq, euler, hcf, relprime, eulerWithSCSCP, sumEulerWithSCSCP-- are we talking directly to a GAP server or a Haskell-side Coordination server------------------------------------------------------------------------------- Compiling in parallel picks the multi-threaded client ParSCSCP.hs module.-- Compiling sequentially picks the (older) SCSCP_API.hs module.-- This is the start of a ghci-based shell, using SCSCP calls for computer algebra-- cash: the computer algebra shell---- Time-stamp: {-# OPTIONS_GHC -cpp -XParallelListComp -XScopedTypeVariables #-}ad>n,f$ u t U T ' K  c b .   l F E ! u b # pS/  if null zs then fromInteger 1 else foldl1 (*) zs in zs = xs `bagInter` ys ys = factors y xs = factors xmyGcd x y = let -- myGcd :: Arith -> Arith -> ArithmyGcd :: (Num a, Factorisable a) => a -> a -> a | otherwise = bagInter xs ysbagInter (x:xs) ys | elem x ys = x:(bagInter xs (delete x ys))bagInter [] _ = []bagInter :: (Eq a) => [a] -> [a] -> [a] factors p1@(Polynomial _) = call1 scscp_WS_Factors p1instance Factorisable Arith where factors = call1 scscp_WS_FactorsIntinstance Factorisable Integer where factors = call1 scscp_WS_FactorsIntinstance Factorisable Int where factors :: a -> [a]class Factorisable a where fromOM pOM = P pOM toOM (P pOM) = pOMinstance OMData (Polynomial a) wherepolyFromString = fromOM . toOMpolyFromString :: String -> Arith -- Polynomial Int fromInteger n = fromOM $ toOM ("0*x_1+"++(show n)) signum = error "signum on Polynomial not implemented" abs = error "abs on Polynomial not implemented" (+) p1@(Polynomial _) p2@(Polynomial _) = call2 scscp_WS_SumPoly p1 p2 (*) p1@(Polynomial _) p2@(Polynomial _) = call2 scscp_WS_ProdPoly p1 p2instance Num (Arith {-Polynomial a-}) where (P p1) == (P p2) = p1 == p2instance Eq a => Eq (Polynomial a) where show (P pOM) = fromOM pOMinstance Show a => Show (Polynomial a) wherenewtype Polynomial a = P OMObjb_sparse_9 = [0, 0, 0, 7, 0, 0, 0, 0, 11] [ 57, 0, 0, 0, 2, 0, 0, 0, 92 ]] [ 0, 19, 0, 0, 0, 0, 7, 1, 0], [ 0, 0, 26, 0, 0, 0, 1, 0, 46], [ 0, 0, 0, 0, 0, 1, 36, 0, 0], [ 27, 0, 35, 0, 1, 0, 0, 0, 11], [ 0, 125, 0, 1, 0, 0, 572, 0, 0], [ 0, 0, 3, 0, 0, 0, 0, 0, 42], [ 0, 1, 0, 0, 0, 0, 0, 0, 0], [ [ 763, 0, 0, 0, 633, 0, 0, 45, 0],a_sparse_9 = addmd3wpB. n ,   i F + p o n T D C $ p Y X W 4 '  t]&%&VFoWRK$yx^B#" sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p /= 0] whereprimes = sieve [2..]primes :: [Integer]fromOMList (MatrixRow xs) = xsfromOMList (Matrix xs) = xsfromOMList (List xs) = xstoOMList xs = Math.ComputerAlgebra.Cash.SGPTypes.List xstoOMMatrix xs = Matrix xs#endif res = g ps (toOMMatrix resL) resL = parZipWith f ps xList xList = zipWith h ps (repeat x) where resmultHomImg h f g ps x = Arith -- result-} Arith -> -- input (matrix, vector) [ Integer ] -> -- hom. imgs. to use. NOTE - will be supplied in a vector format! ([Integer] -> Arith -> Arith) -> -- combine the results to an overall result (Integer -> Arith -> Arith) -> -- solve the problem in the hom. imgs. (Integer -> Arith -> Arith ) -> -- map input to homomorphic imagesmultHomImg :: -- :: (Trans p, Trans c', Trans b') => taskList _ _ _ = [] | otherwise = taskList rs (ps, ts2) pe taskList (r:rs) ( p:ps, t2:ts2 ) pe | pe == r = (p, t2) : (taskList rs (ps, ts2) pe) where distributeLists tasks reqs = [ taskList reqs tasks n | n <- [ 1 .. noPe ] ] -- distributeLists :: ([t], [t]) -> [Int] -> [[(t,t)]] worker f ((p, t2) : ts) = (f p t2) : worker f ts worker f [] = [] -- worker :: (Trans a, Trans b) => (a -> b -> c) -> [(a,b)] -> [c] -- worker f [] = [] requests = (concat (replicate 2 [1..noPe])) ++ newReqs (newReqs, newTasks) = (unzip . concat) (zipWith ( # ) workerProcs (distributeLists (primes, list2) requests)) -- (zipWith (#) workerProcs (distributeLists (list1, list2) requests)) workerProcs = [process (zip [n,n..] . (worker f)) | n <- [1..noPe] ] where = newTasksparZipWith f primes list2 -- list3instance Trans (Arith)instance NFData (Arith) toMatrix (x:xs) = Matrix (map (\z -> MatrixRow (map toNum z)) (x:xs)) toMatrix :: [ [Integer] ] -> ArithtoVector xs = MatrixRow (map (\z -> Num z) xs)toVector :: [Integer] -> ArithtoNum x = Num xtoNum :: Integer -> Arith = multHomImg (call2 scscp_WS_Mod) (call2 scscp_WS_Sol) (call2 scscp_WS_CRA) ps (toOMList ((toMatrix ms):[toOMList (map toNum vs)]))linearSolver ps ms vs -> Arith -> [ Integer ] -> [ [Integer] ] linearSolver :: [ Integer ] #ifdef __PARALLEL_HASKELL__ releaseServer -- shutdown -- do the computation ... ----------------------------------------------------------------------------- #endif putStrLn $ "Are the two results the same: "++(show (x==y)) putStrLn $ "Result: "++(show y) let y = sumEuler_seq n putStrLn $ "Running sumEuler_seq "++(show n)++" ..." putStrLn $ "Result: "++(show x) x <- sumEulerWithSCSCP n putStrLn $ "Running sumEulerWithSCSCP "++(show n)++" ..." let n = 87#ifdef RUN_SUMEULER -- do the computation ...#endif putStrLn $ "Result: "++(show x) let x = (fromOM resOM) :: Int -- print the result let resOM = callSCSCP fName args let args = map toOM [5::Int]# endif scscpFact# else scscp_WS_Factorial# ifdef GAP_SERVER let fName = ad_}|.- lLA@ m Z C  l k =  b L + <  J  Iqi`+c,~I \B.[3 putStrLn $ "Running factorial 5 ..."#if 0 putStrLn $ "Result: "++(show x) let x = (fromOM resOM) :: Int -- print the result let resOM = callSCSCP fName args let args = map toOM [12::Int]# endif scscp_CS_Phi# else scscp_WS_Phi # ifdef GAP_SERVER let fName = putStrLn $ "Running phi 12 ..." -- do the computation ... -------------------------------------------------------#endif# endif putStrLn $ "Reply: "++(show resOM) let resOM = callSCSCP fName args let args = map toOM ["scscp_transient_1", "WS_Phi"] -- HWL: BROKEN: wrong encoding of args; should be in OMS let fName = Right GetSignature putStrLn $ "Request for GetSignature ..." -- ask for available services# ifdef GAP_SERVER ------------------------------------------------------- putStrLn $ "Reply: "++(show resOM) let resOM = callSCSCP fName args let args = [] let fName = Right GetAllowedHeads putStrLn $ "Request for GetAllowedHeads ..." -- ask for available services -------------------------------------------------------# endif putStrLn $ "Reply: "++(show resOM) let resOM = callSCSCP fName args let args = map toOM ["scscp_transient_1"] let fName = Right GetTransientCD putStrLn $ "Request for GetTransientCD ..." -- ask for available services# ifdef GAP_SERVER ------------------------------------------------------- putStrLn $ "Reply: "++(show resOM) let resOM = callSCSCP fName args let args = [] let fName = Right GetServiceDescr putStrLn $ "Request for GetServiceDescr ..." -- ask for available services -------------------------------------------------------#ifdef RUN_BUILTINS initServer (server "localhost" (Just portNum)) putStrLn ("starting up client, opening port " ++ show portNum) -- init ...doClient portNum = dodoClient :: PortNumber -> IO ()-- polynomials only supported for the Haskell server-- GAP server works fine up to Phi function, but needs name scscp_WS_Phi -- currently only works with the purely Haskell dummyServer-- client for calling Euler totient function ----------------------------------------------------------------------------- return (sum xs) xs <- mapM eulerWithSCSCP [m..n]sumEulerFromToWithSCSCP m n = dosumEulerFromToWithSCSCP :: Int -> Int -> IO Int return (sum xs) xs <- mapM eulerWithSCSCP nssumEulerListSCSCP ns = dosumEulerListSCSCP :: [Int] -> IO Int return (sum xs) xs <- mapM eulerWithSCSCP [1..n]sumEulerWithSCSCP n = dosumEulerWithSCSCP :: Int -> IO Int return x let x = (fromOM resOM) :: Int -- print the result let resOM = callSCSCP fName args let args = map toOM [n] let fName = scscp_WS_Phi -- do the computation ...eulerWithSCSCP n = doeulerWithSCSCP :: Int -> IO Int-----------------------------------------------------------------------------relprime x y = hcf x y == 1relprime :: Int -> Int -> Boolhcf x y = hcf y (rem x y)hcf x 0 = xhcf :: Int -> Int -> Int