End OCCUR.
Section APPEND.
Variable data : Set.
Fixpoint append (q : queue data) : queue data -> queue data :=
fun q2 : queue data =>
match q with
| empty => q2
| input d q' => input data d (append q' q2)
end.

(* Specifications: *)
Lemma append_nil1 : forall q : queue data, append (empty data) q = q.
Lemma append_nil2 : forall q : queue data, append q (empty data) = q.
Lemma input_append :
forall (d : data) (q1 q2 : queue data),
input data d (append q1 q2) = append (input data d q1) q2.
Lemma append_assoc :
forall q1 q2 q3 : queue data,
append q1 (append q2 q3) = append (append q1 q2) q3.
Lemma append_right_non_empty :
forall (q1 q2 : queue data) (d : data),
append q1 (input data d q2) <> empty data.
Lemma case_append_right :
forall (E : Set) (x y : E) (q1 q2 : queue data) (d : data),
match append q1 (input data d q2) with
| empty => x
| input _ _ => y
end = y.
Lemma case_first_value :
forall (E : Set) (x y : E) (d : data) (q : queue data),
first data q = value data d ->
match q with
| empty => x
| input _ _ => y
end = y.
Lemma append_first_out :
forall (q1 : queue data) (d : data),
first_out data (append q1 (input data d (empty data))) = q1.
Lemma append_first :
forall (q1 : queue data) (d : data),
first data (append q1 (input data d (empty data))) = value data d.
Lemma first_out_input :
forall (d0 d1 : data) (q : queue data),
first_out data (input data d0 (input data d1 q)) =
input data d0 (first_out data (input data d1 q)).
Lemma first_input :
forall (d0 d1 : data) (q : queue data),
first data (input data d0 (input data d1 q)) = first data (input data d1 q).