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.

Lemma indices: exists tl, ol = map subscript tl /\ IndexSeq 0 tl.