(* Copyright 2012-2015 by Adam Petcher.				* * Use of this source code is governed by the license described	* * in the LICENSE file at the root of the source tree.		*)
(* RndNat -- a computation that returns a random nat uniformly distributed in a specified range. *)
Set Implicit Arguments.
Definition RndNat_unchecked(n : nat) :=
v <-$ {0,1} ^ (lognat n);
let n := (bvToNat v) in
ret n.
Definition ltNatBool := fun x1 x2 => if (lt_dec x1 x2) then true else false.
(* RndNat uses Repeat to get a number strictly less than n *)
Definition RndNat(n : nat) :=
(Repeat (RndNat_unchecked n) (fun x => (ltNatBool x n))).
Notation "[ 0 '..' n )" := (RndNat n)
(right associativity, at level 77) : comp_scope.
intuition.
unfold RndNat.
eapply (well_formed_Repeat).
unfold eq_dec.
intuition.
eapply eq_nat_dec.
unfold RndNat_unchecked.
eapply well_formed_Bind.
eapply well_formed_Rnd.
intuition.
eapply well_formed_Ret.
eapply filter_In.
intuition.
2:{
unfold ltNatBool.
assert ((if (lt_dec O n) then true else false) = true).
destruct (lt_dec O n).
trivial.
omega.
eapply H0.
}
simpl.
eapply Fold.in_getUnique.
eapply Fold.in_flatten.
econstructor.
split.
eapply in_map_iff.
econstructor.
split.
eauto.
eapply in_getAllBvectors.
specialize (bvNat_zero (lognat n)); intuition.
simpl in *.
left.
eapply H0.
Qed.

Lemma RndNat_support_lt : forall n x,
In x (getSupport (RndNat n)) ->
x < n.