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.

(* Specifications: *)
Lemma card_pos : forall (d : data) (q : queue), (card d q >= 0)%Z.
Lemma card_strct_pos : forall (d : data) (q : queue), In_queue d q -> (card d q > 0)%Z.
Lemma card_null : forall (d : data) (q : queue), ~ In_queue d q -> card d q = 0%Z.
Lemma first_in : forall (d : data) (q : queue data), first data q = value data d -> In_queue data d q.
Lemma in_q_input : forall (d' d : data) (q : queue data), d <> d' -> In_queue data d (input data d' q) -> In_queue data d q.
Lemma not_in_q_input : forall (data : Set) (d' d : data) (q : queue data), d <> d' -> ~ In_queue data d (input data d' q) -> ~ In_queue data d q.
Lemma in_q_output : forall (d : data) (q : queue data), In_queue data d (first_out data q) -> In_queue data d q.
Lemma not_in_q_output : forall (data : Set) (d : data) (q : queue data), ~ In_queue data d q -> ~ In_queue data d (first_out data q).
Lemma equality_from_queue_membership : forall (x y : data) (q : queue data), In_queue data y q -> ~ In_queue data x q -> x <> y.
Lemma not_in_q_input2 : forall (d' d : data) (q : queue data), ~ In_queue data d (input data d' q) -> ~ In_queue data d q.
Lemma input_S_card : forall (d d' : data) (q : queue data), d = d' -> card data eq_data_dec d (input data d' q) = (card data eq_data_dec d q + 1)%Z.
Lemma input_diff_card : forall (d d' : data) (q : queue data), d <> d' -> card data eq_data_dec d (input data d' q) = card data eq_data_dec d q.
Lemma firstout_pred_card : forall (d : data) (q : queue data), first data q = value data d -> card data eq_data_dec d (first_out data q) = (card data eq_data_dec d q - 1)%Z.
Lemma firstout_diff_card : forall (d : data) (q : queue data), first data q <> value data d -> card data eq_data_dec d (first_out data q) = card data eq_data_dec d q.