Section RandomPerm.
Variable D R : Set.
Hypothesis D_EqDec : EqDec D.
Hypothesis R_EqDec : EqDec R.
Variable RndR : Comp R.
Hypothesis RndR_wf : well_formed_comp RndR.
Fixpoint inRange(f : list (D * R))(r : R) :=
match f with
| nil => false
| (d', r') :: f' =>
if (eqb r r') then true
else (inRange f' r)
end.
Definition getUnusedR(f : list (D * R)) :=
Repeat (RndR) (fun r => negb (inRange f r)).
intuition.
destruct (in_dec (EqDec_dec _) x (getSupport (getUnusedR ls1))).
unfold getUnusedR in *.
simpl in i.
apply filter_In in i; intuition.
eapply evalDist_Repeat_eq.
intuition.
rewrite H.
trivial.
eapply filter_In; intuition.
eapply sumList_permutation.
eapply NoDup_Permutation.
eapply filter_NoDup.
eapply getSupport_NoDup.
eapply filter_NoDup.
eapply getSupport_NoDup.
intuition.
apply filter_In in H2; intuition.
eapply filter_In; intuition.
rewrite <- H.
trivial.
apply filter_In in H2; intuition.
eapply filter_In; intuition.
rewrite H.
trivial.
unfold getUnusedR in *.
simpl in n.
apply filter_not_In in n.
intuition.
simpl.
rewrite getSupport_not_In_evalDist_h; intuition.
repeat rewrite ratMult_0_r.
intuition.
simpl.
unfold indicator.
rewrite <- H.
rewrite H0.
repeat rewrite ratMult_0_l.
intuition.
Qed.
induction ls; intuition; simpl in *.
discriminate.
case_eq (eqb x b); intuition.
rewrite eqb_leibniz in H0.
subst.
intuition.
right.
eapply IHls.
rewrite H0 in H.
trivial.
Qed.

Lemma getUnusedR_wf : forall ls r,
inRange ls r = false ->
In r (getSupport RndR) ->
well_formed_comp (getUnusedR ls).