Proof with auto.
unfold NDP.qs, U.qs.
pattern l, (qs (@U.cmp ee ol) U.pick l).
apply qs_parts.rect...
apply U.Mext.
clear l.
intros.
rewrite qs_parts.toBody.
Focus 2.
apply NDP.Mext.
rewrite vec.List_map.
rewrite (vec.vec_round_trip (vec.map (@subscript _ _) v) (qs_parts.body NDP.M NDP.pick (NDP.cmp ee))).
rewrite qs_parts.toBody_cons.
unfold qs_parts.selectPivotPart.
unfold qs_parts.partitionPart.
unfold qs_parts.lowRecPart.
simpl.
repeat rewrite ne_list.map_map.
f_equal.
unfold compose.
apply ne_list.map_ext.
intro.
repeat rewrite ne_tree_monad.map_bind.
repeat rewrite (@mon_assoc ne_tree_monad.M).
simpl.
repeat rewrite ne_tree_monad.map_bind.
repeat rewrite (@mon_assoc ne_tree_monad.M).
rewrite NDP.partition.
rewrite U.partition.
simpl.
repeat rewrite (@mon_assoc ne_tree_monad.M).
apply ne_tree_monad.bind_eq with nat (@fst nat (list ee)) (fun x: prod U.monoid (list (Index ee ol)) => length (fst x)).
simpl.
intros.
repeat rewrite (@mon_assoc ne_tree_monad.M).
simpl.
apply (ne_tree_monad.bind_eq) with nat (@fst nat (list ee)) (fun x: prod U.monoid (list (Index ee ol)) => length (fst x)).
intros.
simpl.
unfold compose.
simpl.
repeat rewrite app_length.
f_equal.
rewrite map_length.
repeat rewrite vec.length.
rewrite H0, H1...
unfold compose in H.
simpl monoid_type in *.
rewrite <- H.
f_equal.
rewrite vec.nth_map.
rewrite vec.remove_map.
rewrite <- vec.List_map.
rewrite simpler_same_values...
rewrite (@U.simplePartition_component (UE ee ol)).
rewrite length_filter.
apply le_lt_trans with (length (vec.remove v x))...
rewrite vec.length...
rewrite <- H.
f_equal.
rewrite vec.nth_map.
rewrite vec.remove_map.
rewrite <- vec.List_map.
rewrite simpler_same_values...
rewrite (@U.simplePartition_component (UE ee ol)).
rewrite length_filter.
apply le_lt_trans with (length (vec.remove v x))...
rewrite vec.length...
Qed.

(* Specifications: *)
Theorem qs_CM_U_expec_cost_eq (tl: list (Index ee ol)):
expec cost (NDP.qs ee (map (@subscript ee ol) tl))
= monoid_expec (m:=U.monoid) length (U.qs tl).