Set Implicit Arguments.
Unset Strict Implicit.

Require Export Subsig.

Section Tools.

Variable A : Set.

Fixpoint nfirst_l (n : nat) (l : list A
                             ) {struct n} : list A :=
  match n, l with
  | O, _ => nil (A:=A)
  | S n, a :: l => a :: nfirst_l n l
  | S n, x => x
  end.

Lemma nfirst_l_prefix :
 forall (n : nat) (l : list A), prefix (eq (A:=A)) l (nfirst_l n l).
  intros n; elim n; simpl in |- *; auto.
    intros; apply prefix_nil; auto.
    intros m HR l; case l; simpl in |- *.
      intros; apply prefix_nil; auto.
      intros; apply prefix_cons; auto.
Defined.

Fixpoint nfirst_sig (n : nat) :
 forall l : list A, sigtel l -> sigtel (nfirst_l n l) :=
  match n return (forall l : list A, sigtel l -> sigtel (nfirst_l n l)) with
  | O => fun l s => Esig A
  | S n =>
      fun l =>
      match l return (sigtel l -> sigtel (nfirst_l (S n) l)) with
      | nil => fun s => s
      | a :: l => fun s => Csig a (fun x : dom s => nfirst_sig n (s x))
      end
  end.              

Lemma nfirst_presub :
 forall (n : nat) (l : list A) (s : sigtel l),
 presub (nfirst_l_prefix n l) s (nfirst_sig n s).
  intros n; elim n; simpl in |- *; auto with sigtel.
  intros m HR l s; pattern l, s in |- *; apply sigtel_rect; auto with sigtel.
Defined.

Definition nfirst_subsig (n : nat) (l : list A) (s : sigtel l) :=
  presub_subsig (nfirst_presub n s).

Require Import Mixtels.

Definition sig_of_mix (l : list A) (s : sigtel l) (p : pre l)
  (m : mixtel s p) := s.
Definition pre_of_mix (l : list A) (s : sigtel l) (p : pre l)
  (m : mixtel s p) := p.
Definition sig_of_impl (l : list A) (s : sigtel l) (i : impltel s) := s.

End Tools.
