(* Primitive generator combinators and some basic soundness
   assumptions about them *)
Axiom randomRBool : bool * bool -> RandomSeed -> bool * RandomSeed.Axiom randomRBoolCorrect :
  forall b b1 b2, implb b1 b2 ->
    (implb b1 b && implb b b2 <->
    exists seed, (fst (randomRBool (b1, b2) seed)) = b).Axiom randomRNat  : nat  * nat -> RandomSeed -> nat * RandomSeed.Axiom randomRNatCorrect:
  forall n n1 n2, n1 <= n2 ->
    (n1 <= n <= n2 <->
    exists seed, (fst (randomRNat (n1, n2) seed)) = n).Axiom randomRInt  : Z * Z    -> RandomSeed -> Z * RandomSeed.Axiom randomRIntCorrect:
  forall z z1 z2, Z.leb z1 z2 ->
    (Z.leb z1 z && Z.leb z z2 <->
    exists seed, (fst (randomRInt (z1, z2) seed)) = z).Axiom randomRN    : N * N    -> RandomSeed -> N * RandomSeed.Axiom randomRNCorrect:
  forall n n1 n2,
    N.leb n1 n2 ->
    N.leb n1 n && N.leb n n2 <->
    exists seed, fst (randomRN (n1, n2) seed) = n.CoInductive RandomSeed : Type :=
  | Node : bool -> RandomSeed -> RandomSeed -> RandomSeed.CoInductive RandomSeed : Type :=
  | Node : bool -> RandomSeed -> RandomSeed -> RandomSeed.Definition randomSplit (s : RandomSeed) :=
    match s with
    | Node b s1 s2 => (s1,s2)
    end.

Lemma randomSplitAssumption : forall s1 s2 : RandomSeed, exists s, randomSplit s = (s1,s2).