import system.io universes u def tst1 : nat := let s := mk_std_gen, /- create standard random number generator -/ (v, s') := rand_nat s 0 100 /- generate a random nat in [0, 100]. -/ in v #eval tst1 def tst2 : bool × bool × bool × bool := let s := mk_std_gen, /- create standard random number generator -/ (b₁, s₁) := rand_bool s, /- generate a random Boolean -/ (b₂, s₂) := rand_bool s₁, /- generate another random Boolean -/ (b₃, s₃) := rand_bool s₂, (b₄, _) := rand_bool s₃ in (b₁, b₂, b₃, b₄) #eval tst2 /- `rand_list sz g lo hi` generates a list of size `sz` with random nat's in [lo, hi] generated by `g`. -/ def rand_list : nat → std_gen → nat → nat → list nat × std_gen | 0 g lo hi := ([], g) | (n+1) g lo hi := let (l, g₁) := rand_list n g lo hi, (v, g₂) := rand_nat g₁ lo hi in (v::l, g₂) #eval (rand_list 20 mk_std_gen 0 10).1 /- Version of rand_list that is parametrized by any random number generator implementation -/ def gen_rand_list {gen : Type u} [random_gen gen] : nat → gen → nat → nat → list nat × gen | 0 g lo hi := ([], g) | (n+1) g lo hi := let (l, g₁) := gen_rand_list n g lo hi, (v, g₂) := rand_nat g₁ lo hi in (v::l, g₂) #eval (gen_rand_list 20 mk_std_gen 0 10).1 /- We can implement our own number generators. Here is a 'dumb' one that just generates a sequence -/ structure dummy_gen := (lo hi : nat) (next : nat := lo) instance : random_gen dummy_gen := { range := λ s, (s.lo, s.hi), next := λ s, (s.next, {next := s.next + 1, ..s}), split := λ s, (s, s) } def mk_dummy_gen (lo : nat := 0) (hi : nat := 100000) : dummy_gen := {lo := lo, hi := hi} /- Invoke gen_rand_list using the dummy generator. -/ #eval (gen_rand_list 20 mk_dummy_gen 0 10).1 open io /- The io monad has a number generator. The action `rand` generates a random number. -/ def prg₁ : io unit := do v₁ ← rand, put_str_ln (to_string v₁), v₂ ← rand 0 100, -- we can provide lower and upper bounds put_str_ln (to_string v₂) #eval prg₁ #eval prg₁ /- generate different results since the "World" was modified by previous eval -/ /- The default number generator for the io monad is based on the C++ std::rand procedure, but the user can use set_rand_gen to modify it. -/ def prg₂ : io unit := do set_rand_gen mk_std_gen, prg₁ #eval prg₂ #eval prg₂ /- generate same result -/