Section RndListElem.
Variable A : Set.
Hypothesis eqd : EqDec A.
Local Open Scope list_scope.
Definition rndListElem(ls : list A) : Comp (option A) :=
match (length ls) with
| O => ret None
| S _ =>
i <-$ [0 .. (length ls));
ret (nth_option ls i)
end.
intuition.
unfold rndListElem.
case_eq (length ls); intuition; wftac.
Qed.
End RndListElem.
Local Open Scope list_scope.
induction ls; intuition; simpl in *.
discriminate.
destruct i.
inversion H; clear H; subst.
intuition.
right.
eapply IHls.
eauto.
Qed.
Fixpoint firstIndexOf(A : Set)(eqd : eq_dec A)(ls : list A)(a : A)(def : nat) :=
match ls with
| nil => def
| a' :: ls' =>
if (eqd a a') then O else (S (firstIndexOf eqd ls' a def))
end.
induction ls; intuition; simpl in *;
intuition.
subst.
destruct (eqd a0 a0); subst.
omega.
intuition.
destruct (eqd a0 a); subst.
omega.
eapply lt_n_S.
eauto.
Qed.
induction ls; intuition; simpl in *.
intuition.
intuition.
subst.
destruct (eqd a0 a0); subst; intuition.
destruct (eqd a0 a); subst; intuition.
Qed.
intuition.
unfold rndListElem.
case_eq (length ls); intuition.
exfalso.
destruct ls; simpl in *; intuition.
eapply getSupport_In_Seq.
eapply in_getSupport_RndNat.
rewrite <- H0.
eapply firstIndexOf_in_lt; eauto.
simpl.
left.
eapply nth_firstIndexOf; trivial.
unfold rndListElem in *.
repeat simp_in_support.
discriminate.
eapply nth_option_In; eauto.
Grab Existential Variables.
apply O.
unfold eq_dec.
eapply (EqDec_dec eqd).
Qed.
induction ls; intuition; simpl in *.
discriminate.
inversion H0; clear H0; subst.
destruct n.
inversion H; clear H; subst.
destruct (eqd a0 a0); subst; intuition.
destruct (eqd a0 a); subst; intuition.
exfalso.
eapply H3.
eapply nth_option_In.
eauto.
Qed.
induction ls; intuition; simpl in *.
omega.
destruct n.
econstructor; eauto.
destruct (IHls n).
omega.
econstructor; eauto.
Qed.
intuition.
unfold rndListElem in *.
case_eq (length ls); intuition.
destruct ls; simpl in *; trivial; discriminate.
rewrite H0 in H.
repeat simp_in_support.
apply RndNat_support_lt in H1.
edestruct (nth_option_some ls); eauto.
rewrite H0.
eauto.
congruence.
subst.
simpl.
intuition.
Qed.
intuition.
destruct a1.
destruct a2.
rewrite <- rndListElem_support in *.
unfold rndListElem.
case_eq (length ls); intuition.
destruct ls; simpl in *. intuition. omega.
eapply comp_spec_impl_eq.
eapply comp_spec_seq.
apply (Some a).
apply (Some a).
eapply eq_impl_comp_spec.
eapply well_formed_RndNat.
omega.
eapply well_formed_RndNat.
omega.
eapply RndNat_uniform.
3:{
intros.
simpl in H5.
eapply comp_spec_ret.
assert (a1 = (firstIndexOf (EqDec_dec _) ls a 0) <->
b = (firstIndexOf (EqDec_dec _) ls a0 0)).
eapply H5.
clear H5.
intuition; subst.
rewrite H5.
eapply nth_firstIndexOf; trivial.
symmetry.
eapply nth_firstIndexOf_if; intuition.
rewrite H7.
eapply nth_firstIndexOf; trivial.
symmetry.
eapply nth_firstIndexOf_if; intuition.
}
rewrite <- H2.
apply firstIndexOf_in_lt; trivial.
rewrite <- H2.
apply firstIndexOf_in_lt; trivial.
apply rndListElem_support in H0.
apply rndListElem_support_None in H1.
subst.
simpl in *.
intuition.
destruct a2.
apply rndListElem_support in H1.
apply rndListElem_support_None in H0.
subst.
simpl in *.
intuition.
intuition.
Qed.
induction ls; intuition; simpl in *.
discriminate.
destruct i.
inversion H0; clear H0; subst.
intuition.
eapply IHls; eauto.
Qed.
induction 1; intuition; simpl in *.
intuition; subst.
destruct (eqd a' a'); subst; intuition.
destruct i; intuition.
eapply not_in_nth_option; eauto.
destruct i; intuition.
inversion H3; clear H3; subst.
destruct (eqd a' a'); subst; intuition.
destruct (eqd a' x); subst; intuition.
eapply IHNoDup; eauto.
Qed.
induction ls; intuition; simpl in *.
omega.
destruct i.
discriminate.
assert (i < length ls).
omega.
eauto.
Qed.
intuition.
unfold rndListElem.
case_eq (length ls1); intuition.
rewrite <- H1.
rewrite H4.
eapply comp_spec_ret; intuition.
discriminate.
discriminate.
rewrite <- H1.
rewrite H4.
eapply comp_spec_seq; try eapply None.
eapply eq_impl_comp_spec.
eapply well_formed_RndNat; omega.
eapply well_formed_RndNat; omega.
eapply (@RndNat_uniform  (firstIndexOf (EqDec_dec _) ls1 a1 O) (firstIndexOf (EqDec_dec _) ls2 a2 O)).
rewrite <- H4.
apply firstIndexOf_in_lt; trivial.
rewrite <- H4.
rewrite H1.
apply firstIndexOf_in_lt; trivial.
intuition.
eapply comp_spec_ret.
intuition.
destruct (eq_nat_dec a (firstIndexOf (EqDec_dec _) ls1 a1 O)).
subst.
assert (b = firstIndexOf (EqDec_dec _) ls2 a2 0); intuition.
subst.
repeat rewrite nth_firstIndexOf; intuition.
assert (b <> firstIndexOf (EqDec_dec _) ls2 a2 0).
intuition.
exfalso.
eapply nth_firstIndexOf_None.
eapply H.
eapply H2.
eapply n0.
eauto.
intuition.
destruct (eq_nat_dec a (firstIndexOf (EqDec_dec _) ls1 a1 O)).
subst.
assert (b = firstIndexOf (EqDec_dec _) ls2 a2 0); intuition.
subst.
repeat rewrite nth_firstIndexOf; intuition.
assert (b <> firstIndexOf (EqDec_dec _) ls2 a2 0).
intuition.
exfalso.
eapply nth_firstIndexOf_None.
eapply H0.
eapply H3.
eapply H10.
eauto.
intuition.
Qed.

Theorem rndListElem_support_exists :
forall (A : Set)(eqd : EqDec A)(ls : list A),
exists x,
In x (getSupport (rndListElem eqd ls)).