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.

Lemma concat_cons :
forall (a a' : A) (v v' : seq n A) (w w' : seq m A),
a =' a' in _ ->
v =' v' in _ -> w =' w' in _ -> (a';; v') ++ w' =' a;; v ++ w in _.