Section DEF_FIFO.
(* definition d'une file d'attente comme d'une liste avec un acces a chaque extremite *)
Variable data : Set.
Inductive queue : Set :=
| empty : queue
| input : data -> queue -> queue.
Inductive exc : Set :=
| value : data -> exc
| error : exc.
Definition last (q : queue) :=
match q with
| empty => error
| input d _ => value d
end.
Fixpoint first (q : queue) : exc :=
match q with
| empty => error
| input d q' =>
match q' with
| empty => value d
| input _ _ => first q'
end
end.
Fixpoint first_out (q : queue) : queue :=
match q with
| empty => empty
| input d q' =>
match q' with
| empty => empty
| input _ _ => input d (first_out q')
end
end.
Fixpoint In_queue (d : data) (q : queue) {struct q} : Prop :=
match q with
| empty => False
| input d' q' => d = d' \/ In_queue d q'
end.
(* lorsque l'egalite est decidable, on peut compter le nombre d'occurence d'un element dans la liste *)
Hypothesis eq_data_dec : eq_dec data.
Fixpoint card (d : data) (q : queue) {struct q} : Z :=
match q with
| empty => 0%Z
| input d' q' =>
if eq_data_dec d d'
then (card d q' + 1)%Z
else card d q'
end.

Lemma card_pos : forall (d : data) (q : queue), (card d q >= 0)%Z.