(* 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.
intuition.
unfold RndNat in *.
simpl in *.
eapply filter_In in H.
intuition.
unfold ltNatBool in *.
destruct (lt_dec x n); congruence.
Qed.
Hint Resolve well_formed_RndNat : wftac.
intuition.
unfold RndNat_unchecked.
eapply getSupport_In_Seq.
eapply in_getAllBvectors.
simpl.
left.
eapply bvToNat_natToBv_inverse.
eapply lognat_monotonic.
omega.
Qed.
Local Open Scope rat_scope.

Lemma RndNat_uniform : forall v1 v2 n,
v1 < n ->
v2 < n ->
evalDist (RndNat n) v1 == evalDist (RndNat n) v2.