Random sampling for an element #
We implement sampling to find an element with a given property, for instance being prime or being coprime to a given number. For this we need a hypothesis that such an element exists.
We use the IO
monad to generate random numbers. This is because a random number is not a function, in the sense of having value determined by arguments.
The basic way we sample is to choose an element at random from the list, and then check if it satisfies the property. If it does, we return it. If not, we remove it from the list and try again. To show termination we see (following a lab) that the length of the list decreases by at least one each time.
Removing an element from a list does not increase length
Removing a member from a list shortens the list
We pick an index of the list l
, which is of type Fin l.length
. Rather than proving that the random number generator has this property we pass mod n
.
A random element with a given property from a list. As IO may in principle give an error, we specify a default to fallback and the conditions that this is in the list and has the property p
Equations
- pickElemD l p default h₁ h₂ = Option.getD (EStateM.run' (pickElemIO l p ⋯) ()) { val := default, property := ⋯ }
Instances For
Random Monad #
We used the IO Monad which has a lot of stuff besides randomness. We will now demistify this by constructing a Monad for randomness only.
Equations
- RandomM.rand lo hi gen = randNat gen lo hi
Instances For
Equations
- RandomM.run x = x
Instances For
Equations
- RandomM.run' x gen = (x gen).1
Instances For
Equations
- RandomM.randBool = do let n ← RandomM.rand 0 1 pure (n == 0)
Instances For
Equations
- RandomM.randList lo hi 0 = pure []
- RandomM.randList lo hi (Nat.succ k) = do let x ← RandomM.rand lo hi let xs ← RandomM.randList lo hi k pure (x :: xs)
Instances For
Equations
- RandomM.setSeed n x = ((), mkStdGen n)
Instances For
Equations
- RandomM.withSeed n c = do RandomM.setSeed n c
Instances For
Equations
- StateM'.run x = x
Instances For
Equations
- StateM'.run' x s = (x s).1
Instances For
Equations
- StateM'.setState s x = ((), s)
Instances For
Equations
- StateM'.getState s = (s, s)
Instances For
Equations
- StateM'.withState s c = do StateM'.setState s c