Section MAIN.
Variable A : Setoid.
(** %\label{concat}% *)
Definition concat :
forall (n m : Nat) (f : seq n A) (g : seq m A), seq (n + m) A.
simple induction n.
simpl in |- *.
intros.
exact g.
intros.
simpl in |- *.
exact (f (Build_finiteT (lt_O_Sn n0));; X _ (Seqtl f) g).
(* ie. (concat (f0 :: (Seqtl f) g)) = f0 :: (concat (Seqtl f) g) *)
Defined.
Infix "++" := concat (at level 60, right associativity).
simple induction n.
intros.
simpl in |- *.
assumption.
(* the induction step *)
intros.
set (fg := f ++ g) in |- *.
set (fg' := f' ++ g') in |- *.
simpl in |- *.
red in |- *.
destruct x.
destruct index as [| n1].
unfold fg in |- *.
unfold fg' in |- *.
simpl in |- *.
auto with algebra.
(**)
apply Trans with ((Seqtl f ++ g) (Build_finiteT (lt_S_n _ _ in_range_prf)));
auto with algebra.
apply Trans with ((Seqtl f' ++ g') (Build_finiteT (lt_S_n _ _ in_range_prf)));
auto with algebra.
apply Ap_comp; auto with algebra.
apply (H _ (Seqtl f) (Seqtl f') g g'); auto with algebra.
change (Seqtl f =' Seqtl f' in _) in |- *.
apply Seqtl_comp; auto with algebra.
Qed.
Hint Resolve concat_comp: algebra.
Variable n m : Nat.
intros.
apply Trans with ((a;; v) ++ w).
intro i.
destruct i.
destruct index as [| n0].
simpl in |- *.
auto with algebra.
rename in_range_prf into p.
apply Trans with ((v ++ w) (Build_finiteT (lt_S_n _ _ p))); auto with algebra.
apply Trans with ((Seqtl (a;; v) ++ w) (Build_finiteT (lt_S_n _ _ p)));
auto with algebra.
change ((a;; v) ++ w =' (a';; v') ++ w' in seq (S n + m) A) in |- *.
apply concat_comp; auto with algebra.
Qed.
Hint Resolve cons_concat: algebra.
intros; apply Sym; apply cons_concat; auto with algebra.
Qed.
Hint Resolve concat_cons: algebra.
intros.
intro i.
destruct i.
destruct index as [| n0].
simpl in |- *.
auto with algebra.
rename in_range_prf into p.
apply Trans with ((v ++ v') (Build_finiteT (lt_S_n _ _ p)));
auto with algebra.
apply Trans with ((Seqtl (a;; v) ++ v') (Build_finiteT (lt_S_n _ _ p)));
auto with algebra.
Qed.
intros.
apply Trans with (head v); auto with algebra.
Qed.

Lemma head_eats_concat :
forall (v : seq (S n) A) (w : seq m A), head (v ++ w) =' head v in _.