(* This program is free software; you can redistribute it and/or      *)
(* modify it under the terms of the GNU Lesser General Public License *)
(* as published by the Free Software Foundation; either version 2.1   *)
(* of the License, or (at your option) any later version.             *)
(*                                                                    *)
(* This program is distributed in the hope that it will be useful,    *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of     *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *)
(* GNU General Public License for more details.                       *)
(*                                                                    *)
(* You should have received a copy of the GNU Lesser General Public   *)
(* License along with this program; if not, write to the Free         *)
(* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *)
(* 02110-1301 USA                                                     *)
Require Export Bool.
Require Export fifo.
Unset Standard Proposition Elimination Names.
Section REDUCE.
Variable E : Set.
Variable f : E -> Z.
Fixpoint reduce (q : queue E) : Z :=
match q with
| empty => 0%Z
| input d q' => (reduce q' + f d)%Z
end.
Hypothesis positive_function : forall a : E, (f a > 0)%Z.

(* 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.
(* We prove the following general lemma. Then, we instantiate it to - q1=nil: this case corresponds to adding an element in a queue. - q2=nil: this case corresponds to removing an element from a queue. *)
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.