Section ShuffleList.
Variable A : Set.
Hypothesis A_EqDec : EqDec A.
Definition shuffle(ls : list A) :=
o <-$ rndListElem _ (getAllPermutations ls);
ret
match o with
| None => nil
| Some x => x
end.
intuition.
unfold shuffle in *.
repeat simp_in_support.
destruct x.
eapply Permutation_sym.
eapply getAllPermutations_perms.
apply rndListElem_support in H0.
trivial.
apply rndListElem_support_None in H0.
exfalso.
eapply getAllPermutations_not_nil.
eauto.
Qed.
Fixpoint permute(ls : list A)(sigma : list nat) : list A :=
match sigma with
| nil => nil
| n :: sigma' =>
match (nth_error ls n) with
| None => nil
| Some a => a :: (permute ls sigma')
end
end.
induction ls; destruct n; intuition; simpl in *.
omega.
omega.
inversion H0.
eapply IHls; eauto.
omega.
Qed.
induction sigma; intuition; simpl in *.
case_eq (nth_error ls a); intuition.
simpl.
f_equal.
eapply IHsigma; intuition.
exfalso.
eapply nth_error_not_None.
eapply H.
intuition.
trivial.
Qed.
intuition.
unfold shuffle in *.
repeat simp_in_support.
destruct x.
eapply rndListElem_support in H0.
eapply getAllPermutations_perms.
trivial.
eapply rndListElem_support_None in H0.
exfalso.
eapply getAllPermutations_not_nil.
eauto.
Qed.
intuition.
unfold shuffle.
wftac.
eapply rndListElem_wf.
Qed.
End ShuffleList.
Definition RndPerm(n : nat) :=
shuffle _ (allNatsLt n).

Theorem list_pred_map_both':
forall (A B C D : Set) (lsa : list A) (lsb : list B)
(P : C -> D -> Prop) (f : A -> C)(g : B -> D),
list_pred (fun (a : A) (b : B) => P (f a) (g b)) lsa lsb ->
list_pred P (map f lsa) (map g lsb).