Section contents.
Variables (ee: E) (ol: list ee).
Let qs := @U.qs ee ol.
Proof with auto with arith. (* simpler version of the one below. doesn't provide (i < j), and doesn't need NoDup l *)
subst qs. unfold U.qs.
intro.
pattern l, (qs_definitions.mon_nondet.qs (U.cmp (e:=ee) (ol:=ol)) U.pick l).
apply U.qs_ind.
Focus 1.
simpl.
intros r H.
inversion_clear H.
simpl.
intros.
elimtype False...
intros.
cset (NeTree_In_Node_inv H0). clear H0.
destruct (ne_tree.InL_map_inv _ _ H2). clear H2. destruct H0.
destruct (ne_tree.In_map_inv _ _ H0). clear H0. destruct H3.
subst r.
unfold monoid_expec.map_fst in H1.
unfold fst in H1.
destruct (in_app_or _ _ _ H1); clear H1.
destruct (In_map_inv H0). clear H0. destruct H1.
unfold U.unordered_nat_pair in H0.
unfold IndexIn.
destruct (le_lt_dec x1 (vec.nth v x)); destruct (pair_eq_inv H0); split; subst; apply in_map.
apply vec.remove_In with x...
apply vec.In_nth.
apply vec.In_nth.
apply vec.remove_In with x...
destruct (ne_tree_monad.In_bind_inv _ _ H3). clear H3. destruct H1.
unfold U.M in H3.
rewrite MonoidMonadTrans.bind_toLower in H3.
rewrite (@mon_assoc ne_tree_monad.M ) in H3.
destruct (ne_tree_monad.In_bind_inv _ _ H3). clear H3. destruct H4.
revert H0.
rewrite (@mon_assoc ne_tree_monad.M) in H4.
rewrite MonoidMonadTrans.ret_toLower in H4.
rewrite (@mon_lunit ne_tree_monad.M) in H4.
simpl @fst in H4.
rewrite (@mon_lunit ne_tree_monad.M) in H4.
simpl @fst in H4.
unfold snd in H4.
inversion_clear H4.
simpl.
rewrite app_nil_r.
intros.
assert (forall k cr, IndexIn k (filter (fun f: Index ee ol => unsum_bool (cmp_cmp (Ecmp ee (subscript f) (subscript (vec.nth v x))) cr)) (vec.to_list (vec.remove v x))) -> IndexIn k (vec.to_list v)).
intros.
unfold IndexIn in *.
apply (incl_In _ H4).
apply incl_map.
apply incl_trans with (vec.to_list (vec.remove v x))...
apply SkipList_incl.
apply vec.SkipList_remove.
destruct (in_app_or _ _ _ H0).
destruct (H x Lt x1 H1 _ _ H5).
split; apply H4 with Lt...
destruct (H x Gt x2 H3 _ _ H5).
split; apply H4 with Gt...
Qed.

Theorem qs_sound_cmps: forall l,
forall r, ne_tree.In r (qs l) -> NoDup l ->
forall i j, In (i, j) (fst r) -> i < j.