src/HOL/Tools/Mirabelle/mirabelle_util.ML
changeset 74986 fc664e4fbf6d
child 76183 8089593a364a
equal deleted inserted replaced
74985:ac3901e4e0a9 74986:fc664e4fbf6d
       
     1 (*  Title:      HOL/Mirabelle/Tools/mirabelle_util.ML
       
     2     Author:     Martin Desharnais, MPI-INF Saarbruecken
       
     3 *)
       
     4 
       
     5 (* Pseudorandom number generator *)
       
     6 signature PRNG = sig
       
     7   type state
       
     8   val initialize : int -> state
       
     9   val next : state -> int * state
       
    10 end
       
    11 
       
    12 (* Pseudorandom algorithms *)
       
    13 signature PRNG_ALGORITHMS = sig
       
    14   include PRNG
       
    15   val shuffle : state -> 'a list -> 'a list * state
       
    16 end
       
    17 
       
    18 functor PRNG_Algorithms(PRNG : PRNG) : PRNG_ALGORITHMS = struct
       
    19 
       
    20 open PRNG
       
    21 
       
    22 fun shuffle prng_state xs =
       
    23   fold_map (fn x => fn prng_state =>
       
    24     let
       
    25       val (n, prng_state') = next prng_state
       
    26     in ((n, x), prng_state') end) xs prng_state
       
    27   |> apfst (sort (int_ord o apply2 fst))
       
    28   |> apfst (map snd)
       
    29 
       
    30 end
       
    31 
       
    32 (* multiplicative linear congruential generator *)
       
    33 structure MLCG_PRNG : PRNG = struct
       
    34   (* The modulus is implicitly 2^64 through using Word64.
       
    35      The multiplier and increment are the same as Newlib and Musl according to Wikipedia.
       
    36      See: https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use
       
    37    *)
       
    38   val multiplier = Word64.fromInt 6364136223846793005
       
    39   val increment = Word64.fromInt 1
       
    40 
       
    41   type state = Word64.word
       
    42 
       
    43   val initialize = Word64.fromInt
       
    44 
       
    45   fun next s =
       
    46     let
       
    47       open Word64
       
    48       val s' = multiplier * s + increment
       
    49     in
       
    50       (toInt s', s')
       
    51     end
       
    52 end
       
    53 
       
    54 structure MLCG = PRNG_Algorithms(MLCG_PRNG)