Section contents.
Variables (T: E) (ol: list T).
Definition Index := natBelow (length ol).
Definition subscript: Index -> T := vec.nth (vec.insertion_sort (@Ele T) (@Ele_le_dec T) (vec.from_list ol)).
Definition UE: E :=
Build_E (fun x y: Index => Ecmp T (subscript x) (subscript y))
(fun x y => Ecmp_sym T (subscript x) (subscript y))
(fun x y z => Ecmp_trans T (subscript x) (subscript y) (subscript z))
(fun x y z => Ecmp_eq_trans_l T (subscript x) (subscript y) (subscript z)).
Definition IndexIn (i: nat) (l: list Index): Prop := In i (map nb_val l).
Definition IndexSeq (b: nat) (l: list Index): Prop :=
forall i, b <= i -> i < b + length l -> IndexIn i l.
Definition IndexSeq_above (b: nat) (l: list Index): Prop := IndexSeq (b - length l) l.
Proof with try assumption.
repeat intro.
apply lt_asym with (nb_val x) (nb_val y)...
apply IndicesCorrect.
apply Ecmp_apply_sym...
Qed.
Definition IndexSeq_uncons l b:
IndexSeq b l -> l <> nil -> exists l', exists p: Index, nb_val p = b /\ Permutation.Permutation (p :: l') l.
Proof with auto.
destruct l; intros.
intros.
elimtype False...
assert (b < b + length (i :: l)).
simpl. omega.
specialize (H b (le_refl _) H1).
unfold IndexIn in H.
destruct (In_map_inv H). clear H.
destruct H2.
subst b.
destruct (In_inv_perm _ _ H2).
eauto.
Qed.
Proof with auto.
do 4 intro.
assert (b <= i) by omega.
assert (i < b + S (length l)). omega.
cset (H i H2 H3).
unfold IndexIn in *.
destruct (In_map_inv H4). clear H4.
destruct H5.
subst i.
apply in_map.
inversion_clear H5...
subst.
elimtype False.
apply (le_Sn_n x)...
Qed.
Proof with auto.
unfold vec.nb_nats.
intros.
apply vec.perm_sym.
apply vec.NoDup_incl_Permutation.
rewrite <- vec.List_map.
apply NoDup_map.
intros.
apply natBelow_unique...
apply vec.NoDup_nats.
do 2 intro.
rewrite <- vec.List_map in H0.
destruct (In_map_inv H0). clear H0.
destruct H1. subst.
destruct (vec.In_nats_inv _ _ _ H1). clear H1.
rewrite <- vec.List_map.
apply H...
rewrite vec.length.
omega.
Qed.
Proof with auto.
intros.
unfold IndexSeq.
intros.
unfold IndexIn.
apply Permutation.Permutation_in with (vec.to_list (vec.nb_nats b n)).
apply Permutation.Permutation_sym.
cset (vec.List_Permutation H).
rewrite <- vec.List_map in H2...
rewrite vec.length in H1.
apply vec.In_nb_nats'...
Qed.
Definition IndexSeq_NoDup b l: IndexSeq b l -> NoDup l.
Proof with auto.
rewrite <- (vec.list_round_trip l).
cset (vec.from_list l).
intro.
apply (NoDup_map_inv' (@nb_val (length ol))).
rewrite vec.List_map.
assert (Permutation.Permutation (vec.to_list (vec.map nb_val H)) (vec.to_list (vec.nb_nats b (length l)))).
apply vec.List_Permutation, vec_IndexSeq_nats_perm...
rewrite H1.
unfold vec.nb_nats.
rewrite <- vec.List_map.
apply NoDup_map.
intros.
apply natBelow_unique...
apply vec.NoDup_nats.
Qed.
Proof with auto with arith.
rewrite <- (vec.list_round_trip l).
cset (vec.from_list l).
intros.
assert (In (nb_val t) (map nb_val (vec.to_list H))).
apply in_map...
rewrite vec.List_map in H2.
assert (In (nb_val t) (vec.to_list (vec.nb_nats b (length l)))).
apply Permutation.Permutation_in with (vec.to_list (vec.map (nb_val (n:=length ol)) H))...
apply vec.List_Permutation.
apply (vec_IndexSeq_nats_perm H H0).
rewrite vec.length.
rewrite plus_comm.
apply (vec.In_nb_nats_inv _ _ _ H3).
Qed.
Hint Resolve in_map.
Proof with auto.
unfold UE. unfold Ele. simpl.
intros.
intro.
apply lt_irrefl with b.
apply le_lt_trans with e.
destruct (IndexSeq_inv H e H0)...
rewrite Ecmp_sym in H1.
case_eq (Ecmp T (subscript e) (subscript b)); intro; rewrite H2 in H1.
discriminate.
apply (IndicesCorrect e b H2).
discriminate.
Qed.
Proof with auto.
intros.
do 3 intro.
destruct (le_lt_or_eq b i H0).
intros.
unfold IndexSeq in H.
right.
apply H...
simpl in H1.
omega.
subst.
left...
Qed.
Proof with auto.
intros.
destruct (vec.Permutation_mapping (vec.perm_sym (vec.insertion_sort_permutes (@Ele T) (@Ele_le_dec T) (vec.from_list ol)))).
destruct H.
exists (vec.to_list x).
split.
rewrite vec.List_map...
apply vec.eq_list.
symmetry...
unfold IndexSeq.
intros.
unfold IndexIn.
rewrite vec.length in H2.
simpl in H2.
destruct (lt_exists_plus H2). clear H2.
clear H0.
revert H.
revert x.
rewrite H3. clear H3. intros.
cut (In (mkNatBelow i x0) (vec.to_list x))...
intros.
apply (in_map nb_val _ _ H0).
Qed.
Proof with auto with arith.
unfold UE.
simpl.
induction n.
intros.
destruct l.
simpl.
apply IndexSeq_nil.
discriminate.
intros.
assert (l <> nil). intro. subst. discriminate.
destruct (IndexSeq_uncons H0 H1).
destruct H2.
destruct H2.
subst b.
replace n with (length x) in *.
Focus 2.
cset (Permutation.Permutation_length H3).
simpl in H2.
unfold Index in H, H2.
rewrite H in H2.
inversion H2...
apply IndexSeq_perm with (filter (fun f => unsum_bool (cmp_cmp (Ecmp T (subscript f) (subscript e)) Lt)) (x0 :: x))...
Focus 2.
apply filter_perm.
repeat intro...
apply Permutation.Permutation_sym...
assert (In x0 (x0 :: x)).
left...
cset (IndexSeq_base_lowest_value' _ (IndexSeq_perm H0 H3) ).
simpl.
case_eq (Ecmp T (subscript x0) (subscript e)); intro.
rewrite (proj1_conj (filter_none (fun f: Index => unsum_bool (cmp_cmp (Ecmp T (subscript f) (subscript e)) Lt)) x))...
intros.
case_eq (Ecmp T (subscript x1) (subscript e))...
intros.
elimtype False.
unfold UE, Ele in H4. simpl in H4.
apply H4 with x1.
right...
apply Ecmp_apply_sym.
simpl.
apply Ecmp_eq_trans_r with (subscript e)...
apply Ecmp_apply_sym...
simpl.
apply IndexSeq_cons...
apply IHn...
apply (IndexSeq_cons_inv (IndexSeq_perm H0 H3)).
rewrite (proj1_conj (filter_none (fun f: Index => unsum_bool (cmp_cmp (Ecmp T (subscript f) (subscript e)) Lt)) x))...
intros.
case_eq (Ecmp T (subscript x1) (subscript e))...
intros.
elimtype False.
apply H4 with x1.
right...
apply Ecmp_apply_sym.
simpl.
apply Ecmp_trans with (subscript e)...
apply Ecmp_apply_sym...
Qed.

Lemma IndexSeq_filterGt e l: forall b, IndexSeq b l ->
IndexSeq_above (b + length l) (filter (fun f => unsum_bool (cmp_cmp (Ecmp UE f e) Gt)) l).