Fixpoint reduce (q : queue E) : Z :=
  match q with
  | empty => 0%Z
  | input d q' => (reduce q' + f d)%Z
  end.

(* Specifications: *)
Lemma sum_positive : forall a b : Z, (a >= 0)%Z -> (b > 0)%Z -> (a + b >= 0)%Z.
Lemma reduce_nil : reduce (empty E) = 0%Z.
Lemma reduce_null_fun : forall q : queue E, (forall d : E, f d = 0%Z) -> reduce q = 0%Z.
Lemma reduce_positive : forall q : queue E, (reduce q >= 0)%Z.
Lemma reduce_append : forall (q1 : queue E) (d : E) (q2 : queue E), reduce (append E q1 (input E d q2)) = (reduce (append E q1 q2) + f d)%Z.
Lemma reduce_append_nil1 : forall (d : E) (q2 : queue E), reduce (input E d q2) = (reduce q2 + f d)%Z.
Lemma reduce_append_nil2 : forall (q1 : queue E) (d : E), reduce (append E q1 (input E d (empty E))) = (reduce q1 + f d)%Z.
Lemma reduce_append_nil2_symmetric : forall (q1 : queue E) (d : E), reduce q1 = (reduce (append E q1 (input E d (empty E))) - f d)%Z.