Section PRP_PRF.
Variable n : nat. (* bit vector length *)
Hint Resolve getUnusedR_wf : wftac.
Hint Resolve well_formed_perm_1 : wftac.
Definition getUnusedBvector := @getUnusedR (Bvector n) _ _ (Rnd n).
Definition well_formed_Bvector_perm := @well_formed_perm (Bvector n) _ _ _ (Rnd n).
Definition randomPerm_Bvector := @randomPerm (Bvector n) _ _ _ (Rnd n).
intuition.
eapply getUnusedR_wf; wftac.
simpl.
eapply in_getAllBvectors.
Qed.
intuition.
eapply well_formed_perm_1 in H.
destruct H.
intuition.
unfold getUnusedBvector.
eapply getUnusedR_wf; wftac.
eauto.
Qed.
Hint Resolve getUnusedBvector_wf : wftac.
(* A random permutation in which the loop that gets an unused value from the range is unrolled one step.  This is useful when comparing to a random function. *)
Definition randomPerm_unroll(p : (list (Bvector n * Bvector n)) * Bvector n) : Comp (list (Bvector n * Bvector n) * Bvector n) :=
let (f, d) := p in
match f#d with
| None => (r <-$ (r0 <-$ {0, 1}^n; if (negb (inRange _ f r0)) then ret r0 else getUnusedBvector f) ; ret ((d, r) :: f, r))
| Some r => ret (f, r)
end.

Lemma randomPerm_unroll_wf : forall ls b0,
(forall x, ls#x = None -> exists r, inRange _ ls r = false) ->
well_formed_comp (randomPerm_unroll (ls, b0)).