
 Time - stamp : < 2010 - 10 - 13   > 

  Module expressing Dates Bill of Material Program 
	   18/9/95 

 * * * * * * * * * * * * * * * * * * * * * * * dateNaive11.hs * * * * * * * * * * * * * * * * * * * * * * * * * * 

 Naive functional version . Generates a list of tuples + explodes by 
 scanning the list . Query is hand - translated into recursive functions 

 This version uses parallel Strategies . The intention is to very 
 clearly seperate computation from evaluation . 


Time-stamp: <2010-10-13 10:22:45 simonmar>

 Module expressing Dates Bill of Material Program
	Phil Trinder 18/9/95

*********************** dateNaive11.hs **************************

Naive functional version. Generates a list of tuples + explodes by
scanning the list. Query is hand-translated into recursive functions

This version uses parallel Strategies. The intention is to very
clearly seperate computation from evaluation.

-}

module Main where

import Parallel
--import ParallelStrategiesIV
import Strategies

#if defined(IO13)
import GranRandom
import System.Environment (getArgs)
#else
import GlaExts
import ST
#endif

----------------------------------------------------------------------------- 
 --   For Hugs ! 

 seq x y = y 

 par x y = y 

--  For Hugs!

seq x y = y

par x y = y
-}

 NB : Ramdom numbers are now taken from GranRandom 
 ------------------------------------------------------------------------------- 
 -- This section replicated from   / lib / Random module for use with Hugs 

 -- Use seeds s1 in 1 .. 2147483562 and s2 in 1 .. 2147483398 to generate 
 -- an infinite list of random Ints . 
 randomInts : : Int - > Int - > [ Int ] 
 randomInts s1 s2 = 
     if 1 < = s1 & & s1 < = 2147483562 then 
         if 1 < = s2 & & s2 < = 2147483398 then 
             rands s1 s2 
         else 
             error " randomInts : Bad second seed . " 
     else 
         error " randomInts : Bad first seed . " 

 rands : : Int - > Int - > [ Int ] 
 rands s1 s2 = z ' : rands s1 '' s2 '' 
         where    z '    = if z < 1 then z + 2147483562 else z 
                 z     = s1 '' - s2 '' 

                 k     = s1 ` quot ` 53668 
                 s1 '   = 40014 * ( s1 - k * 53668 ) - k * 12211 
                 s1 '' = if s1 ' < 0 then s1 ' + 2147483563 else s1 ' 

                 k '    = s2 ` quot ` 52774 
                 s2 '   = 40692 * ( s2 - k ' * 52774 ) - k ' * 3791 
                 s2 '' = if s2 ' < 0 then s2 ' + 2147483399 else s2 ' 

NB: Ramdom numbers are now taken from GranRandom
-------------------------------------------------------------------------------
-- This section replicated from Lennarts hbc/lib/Random module for use with Hugs

-- Use seeds s1 in 1..2147483562 and s2 in 1..2147483398 to generate
-- an infinite list of random Ints.
randomInts :: Int -> Int -> [Int]
randomInts s1 s2 =
    if 1 <= s1 && s1 <= 2147483562 then
        if 1 <= s2 && s2 <= 2147483398 then
            rands s1 s2
        else
            error "randomInts: Bad second seed."
    else
        error "randomInts: Bad first seed."

rands :: Int -> Int -> [Int]
rands s1 s2 = z' : rands s1'' s2''
        where   z'   = if z < 1 then z + 2147483562 else z
                z    = s1'' - s2''

                k    = s1 `quot` 53668
                s1'  = 40014 * (s1 - k * 53668) - k * 12211
                s1'' = if s1' < 0 then s1' + 2147483563 else s1'

                k'   = s2 `quot` 52774
                s2'  = 40692 * (s2 - k' * 52774) - k' * 3791
                s2'' = if s2' < 0 then s2' + 2147483399 else s2'
-}
-------------------------------------------------------------------------------

  suitable tries a sequence of random numbers until it finds one less 
 than n ( the main part ) and that has n't been chosen already
than n (the main part) and that hasn't been chosen already -}

suitable n (r:rs) chosen = if r < n && notElem r chosen then
		      	     (r,rs)
		    	   else
		      	     suitable n rs chosen


genBetween lo hi rs
	| lo == hi 	= []
	| otherwise	= (lo,m1,2):(lo,m2,4):(lo,m3,1):
	                  genBetween (lo+1) hi rs'''
			  where
			    (m1,rs') = suitable lo rs []
			    (m2,rs'') = suitable lo rs' [m1]
			    (m3,rs''') = suitable lo rs'' [m1,m2]
	
explode r ass = nub [p | (m,s,n) <- r, m == ass, p <- (s:explode r s)]
  explode r ass = [ p | ( m , s , n ) < - r , m = = ass ,     s : explode r s ) ]


  Generates 2n tuples in a directed acyclic graph . Each tuple in the 
 range ( n .. n/3 ] is linked to 3 other tuples smaller than it , and no 
 tuple is linked to the same child twice . e.g. generate 12 = 
 [ ( 4,1,2 ) , ( 4,2,4 ) , ( 4,3,1 ) , ( 5,1,2 ) , ( 5,2,4 ) , ( 5,3,1 ) , 
  ( 6,1,2 ) , ( 6,2,4 ) , (  ) , ( 7,4,2 ) , ( 7,3,4 ) , ( 7,2,1 ) , 
  ( 8,1,2 ) , ( 8,2,4 ) , ( 8,3,1 ) , ( 9,3,2 ) , ( 9,4,4 ) , ( 9,5,1 ) , 
  ( 10,5,2 ) , ( 10,4,4 ) , ( 10,3,1 ) , ( 11,2,2 ) , ( 11,1,4 ) , ( 11,3,1 ) ] 

range (n..n/3] is linked to 3 other tuples smaller than it, and no
tuple is linked to the same child twice. e.g. generate 12 =
[(4,1,2), (4,2,4), (4,3,1), (5,1,2), (5,2,4), (5,3,1),
 (6,1,2), (6,2,4), (6,3,1), (7,4,2), (7,3,4), (7,2,1),
 (8,1,2), (8,2,4), (8,3,1), (9,3,2), (9,4,4), (9,5,1),
 (10,5,2), (10,4,4), (10,3,1), (11,2,2), (11,1,4), (11,3,1)]
-}

#if defined(IO13)

generate :: Int -> IO [(Int, Int, Int)]
generate n = getRandomInts n >>= \ rs ->
	     return (genBetween (n `div` 3) n rs)

  First create the list of tuples , then explode ( some ) , finally print 
 out how many in each explosion
out how many in each explosion -}

testChunk :: Int -> Int -> Int -> Int -> IO [Int]
testChunk lo hi bomSize size =
	  generate bomSize >>= \ bom ->
	  let
	    explodeList = map (explode bom) [lo..hi]
	    result = map length explodeList
	    strategy result = (seqList rnf bom) `seq`
	                      (parListChunk size rnf explodeList) `seq`
	                      result
	  in
          return (strategy result)

# if defined(ARGS)
main = 	getArgs >>=  \[a1, a2, a3] ->
	let lo      = fst (head (readDec a1))
	    hi      = fst (head (readDec a2))
	    bomSize = fst (head (readDec a3))
	in
        testChunk lo hi bomSize 3 >>= \ l ->	
#  if defined(PRINT)
	putStr (show l)
#  else
        (rnf l) `seq` putStr "Done\n"
#  endif
# else
main = 	let lo      = 80
	    hi      = 90
	    bomSize = 100
	in
        testChunk lo hi bomSize 3 >>= \ l ->	
#  if defined(PRINT)
	putStr (show l)
#  else
        (rnf l) `seq` putStr "Done\n"
#  endif
# endif

#else  /* !IO13 */

generate :: Int -> [(Int, Int, Int)]
generate n = genBetween (n `div` 3) n rs
	       where
		 rs = map (\x -> mod x n) (randomInts 53 107)

  First create the list of tuples , then explode ( some ) , finally print 
 out how many in each explosion
out how many in each explosion -}

testChunk lo hi bomSize size = let
			 bom = generate bomSize
			 explodeList = map (explode bom) [lo..hi]
		    	 result = map length explodeList
		       in
			 (seqList rnf bom) `seq`
                         (parListChunk size rnf explodeList) `seq`
			 result


#if defined(ARGS)
main = 	getArgs exit ( \[a1, a2, a3] ->
	                  let lo      = fst (head (readDec a1))
			      hi      = fst (head (readDec a2))
			      bomSize = fst (head (readDec a3))
			  in
			    appendChan stdout (show (testChunk lo hi bomSize 3)) abort done
		     )
#else
main = 	let lo      = 70
	    hi      = 90
	    bomSize = 100
	in
	  appendChan stdout (show (testChunk lo hi bomSize 3)) abort done
#endif

#endif /* IO13 */

import ParallelStrategiesIV
--------------------------------------------------------------------------- 
   For Hugs ! 
  For Hugs!
----------------------------------------------------------------------------- 
 This section replicated from   / lib / Random module for use with Hugs 
 Use seeds s1 in 1 .. 2147483562 and s2 in 1 .. 2147483398 to generate 
 an infinite list of random Ints . 
-----------------------------------------------------------------------------
 This section replicated from Lennarts hbc/lib/Random module for use with Hugs
 Use seeds s1 in 1..2147483562 and s2 in 1..2147483398 to generate
 an infinite list of random Ints.
-----------------------------------------------------------------------------

 Time - stamp : < 2010 - 10 - 13   > 

  Module expressing Dates Bill of Material Program 
	   18/9/95 

 * * * * * * * * * * * * * * * * * * * * * * * dateNaive11.hs * * * * * * * * * * * * * * * * * * * * * * * * * * 

 Naive functional version . Generates a list of tuples + explodes by 
 scanning the list . Query is hand - translated into recursive functions 

 This version uses parallel Strategies . The intention is to very 
 clearly seperate computation from evaluation . 


Time-stamp: <2010-10-13 10:22:45 simonmar>

 Module expressing Dates Bill of Material Program
	Phil Trinder 18/9/95

*********************** dateNaive11.hs **************************

Naive functional version. Generates a list of tuples + explodes by
scanning the list. Query is hand-translated into recursive functions

This version uses parallel Strategies. The intention is to very
clearly seperate computation from evaluation.

-}

module Main where

import Parallel
import Strategies

#if defined(IO13)
import GranRandom
import System.Environment (getArgs)
#else
import GlaExts
import ST
#endif


 seq x y = y 

 par x y = y 


seq x y = y

par x y = y
-}

 NB : Ramdom numbers are now taken from GranRandom 

 randomInts : : Int - > Int - > [ Int ] 
 randomInts s1 s2 = 
     if 1 < = s1 & & s1 < = 2147483562 then 
         if 1 < = s2 & & s2 < = 2147483398 then 
             rands s1 s2 
         else 
             error " randomInts : Bad second seed . " 
     else 
         error " randomInts : Bad first seed . " 

 rands : : Int - > Int - > [ Int ] 
 rands s1 s2 = z ' : rands s1 '' s2 '' 
         where    z '    = if z < 1 then z + 2147483562 else z 
                 z     = s1 '' - s2 '' 

                 k     = s1 ` quot ` 53668 
                 s1 '   = 40014 * ( s1 - k * 53668 ) - k * 12211 
                 s1 '' = if s1 ' < 0 then s1 ' + 2147483563 else s1 ' 

                 k '    = s2 ` quot ` 52774 
                 s2 '   = 40692 * ( s2 - k ' * 52774 ) - k ' * 3791 
                 s2 '' = if s2 ' < 0 then s2 ' + 2147483399 else s2 ' 

NB: Ramdom numbers are now taken from GranRandom

randomInts :: Int -> Int -> [Int]
randomInts s1 s2 =
    if 1 <= s1 && s1 <= 2147483562 then
        if 1 <= s2 && s2 <= 2147483398 then
            rands s1 s2
        else
            error "randomInts: Bad second seed."
    else
        error "randomInts: Bad first seed."

rands :: Int -> Int -> [Int]
rands s1 s2 = z' : rands s1'' s2''
        where   z'   = if z < 1 then z + 2147483562 else z
                z    = s1'' - s2''

                k    = s1 `quot` 53668
                s1'  = 40014 * (s1 - k * 53668) - k * 12211
                s1'' = if s1' < 0 then s1' + 2147483563 else s1'

                k'   = s2 `quot` 52774
                s2'  = 40692 * (s2 - k' * 52774) - k' * 3791
                s2'' = if s2' < 0 then s2' + 2147483399 else s2'
-}

  suitable tries a sequence of random numbers until it finds one less 
 than n ( the main part ) and that has n't been chosen already
than n (the main part) and that hasn't been chosen already -}

suitable n (r:rs) chosen = if r < n && notElem r chosen then
		      	     (r,rs)
		    	   else
		      	     suitable n rs chosen


genBetween lo hi rs
	| lo == hi 	= []
	| otherwise	= (lo,m1,2):(lo,m2,4):(lo,m3,1):
	                  genBetween (lo+1) hi rs'''
			  where
			    (m1,rs') = suitable lo rs []
			    (m2,rs'') = suitable lo rs' [m1]
			    (m3,rs''') = suitable lo rs'' [m1,m2]
	
explode r ass = nub [p | (m,s,n) <- r, m == ass, p <- (s:explode r s)]
  explode r ass = [ p | ( m , s , n ) < - r , m = = ass ,     s : explode r s ) ]


  Generates 2n tuples in a directed acyclic graph . Each tuple in the 
 range ( n .. n/3 ] is linked to 3 other tuples smaller than it , and no 
 tuple is linked to the same child twice . e.g. generate 12 = 
 [ ( 4,1,2 ) , ( 4,2,4 ) , ( 4,3,1 ) , ( 5,1,2 ) , ( 5,2,4 ) , ( 5,3,1 ) , 
  ( 6,1,2 ) , ( 6,2,4 ) , (  ) , ( 7,4,2 ) , ( 7,3,4 ) , ( 7,2,1 ) , 
  ( 8,1,2 ) , ( 8,2,4 ) , ( 8,3,1 ) , ( 9,3,2 ) , ( 9,4,4 ) , ( 9,5,1 ) , 
  ( 10,5,2 ) , ( 10,4,4 ) , ( 10,3,1 ) , ( 11,2,2 ) , ( 11,1,4 ) , ( 11,3,1 ) ] 

range (n..n/3] is linked to 3 other tuples smaller than it, and no
tuple is linked to the same child twice. e.g. generate 12 =
[(4,1,2), (4,2,4), (4,3,1), (5,1,2), (5,2,4), (5,3,1),
 (6,1,2), (6,2,4), (6,3,1), (7,4,2), (7,3,4), (7,2,1),
 (8,1,2), (8,2,4), (8,3,1), (9,3,2), (9,4,4), (9,5,1),
 (10,5,2), (10,4,4), (10,3,1), (11,2,2), (11,1,4), (11,3,1)]
-}

#if defined(IO13)

generate :: Int -> IO [(Int, Int, Int)]
generate n = getRandomInts n >>= \ rs ->
	     return (genBetween (n `div` 3) n rs)

  First create the list of tuples , then explode ( some ) , finally print 
 out how many in each explosion
out how many in each explosion -}

testChunk :: Int -> Int -> Int -> Int -> IO [Int]
testChunk lo hi bomSize size =
	  generate bomSize >>= \ bom ->
	  let
	    explodeList = map (explode bom) [lo..hi]
	    result = map length explodeList
	    strategy result = (seqList rnf bom) `seq`
	                      (parListChunk size rnf explodeList) `seq`
	                      result
	  in
          return (strategy result)

# if defined(ARGS)
main = 	getArgs >>=  \[a1, a2, a3] ->
	let lo      = fst (head (readDec a1))
	    hi      = fst (head (readDec a2))
	    bomSize = fst (head (readDec a3))
	in
        testChunk lo hi bomSize 3 >>= \ l ->	
#  if defined(PRINT)
	putStr (show l)
#  else
        (rnf l) `seq` putStr "Done\n"
#  endif
# else
main = 	let lo      = 80
	    hi      = 90
	    bomSize = 100
	in
        testChunk lo hi bomSize 3 >>= \ l ->	
#  if defined(PRINT)
	putStr (show l)
#  else
        (rnf l) `seq` putStr "Done\n"
#  endif
# endif

#else  /* !IO13 */

generate :: Int -> [(Int, Int, Int)]
generate n = genBetween (n `div` 3) n rs
	       where
		 rs = map (\x -> mod x n) (randomInts 53 107)

  First create the list of tuples , then explode ( some ) , finally print 
 out how many in each explosion
out how many in each explosion -}

testChunk lo hi bomSize size = let
			 bom = generate bomSize
			 explodeList = map (explode bom) [lo..hi]
		    	 result = map length explodeList
		       in
			 (seqList rnf bom) `seq`
                         (parListChunk size rnf explodeList) `seq`
			 result


#if defined(ARGS)
main = 	getArgs exit ( \[a1, a2, a3] ->
	                  let lo      = fst (head (readDec a1))
			      hi      = fst (head (readDec a2))
			      bomSize = fst (head (readDec a3))
			  in
			    appendChan stdout (show (testChunk lo hi bomSize 3)) abort done
		     )
#else
main = 	let lo      = 70
	    hi      = 90
	    bomSize = 100
	in
	  appendChan stdout (show (testChunk lo hi bomSize 3)) abort done
#endif

#endif /* IO13 */
