82 lines
2.4 KiB
Text
82 lines
2.4 KiB
Text
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 -/
|