Theory Permuted_Congruential_Generator

section ‹A Pseudo-random Number Generator\label{sec:permuted_congruential_generator}›

text ‹In this section we introduce a PRG, that can be used to generate random bits. It is an
implementation of O'Neil's Permuted congruential generator~\cite{oneill2014}
(specifically PCG-XSH-RR). In empirical tests it ranks high~\cite{bhattacharjee2018, singh2020}
while having a low implementation complexity.

This is for easy testing purposes only, the generated code can be run with any source of random
bits.›

theory Permuted_Congruential_Generator
  imports
    "HOL-Library.Word"
    "Coin_Space"
begin

text ‹The following are default constants from the reference implementation~\cite{pcgbasic}.›

definition pcg_mult :: "64 word"
  where "pcg_mult = 6364136223846793005"
definition pcg_increment :: "64 word"
  where "pcg_increment = 1442695040888963407"

fun pcg_rotr :: "32 word  nat  32 word"
  where "pcg_rotr x r = Bit_Operations.or (drop_bit r x) (push_bit (32-r) x)"

fun pcg_step :: "64 word  64 word"
  where "pcg_step state = state * pcg_mult + pcg_increment"

text ‹Based on \cite[Section~6.3.1]{oneill2014}:›

fun pcg_get :: "64 word  32 word"
  where "pcg_get state =
    (let count = unsigned (drop_bit 59 state);
         x     = xor (drop_bit 18 state) state
      in pcg_rotr (ucast (drop_bit 27 x)) count)"

fun pcg_init :: "64 word  64 word"
  where "pcg_init seed = pcg_step (seed + pcg_increment)"

definition to_bits :: "32 word  bool list"
  where "to_bits x = map (λk. bit x k) [0..<32]"

definition random_coins
  where "random_coins seed = build_coin_gen (to_bits  pcg_get) pcg_step (pcg_init seed)"

end