(* 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                                                     *)
Section my_MapFold.
Variable M : Set.
Variable neutral : M.
Variable op : M -> M -> M.
Variable R : relation M.
Definition F (A : Set) (f : ad -> A -> M) (r : ad * A)
(m : M) := let (a, y) := r in op (f a y) m.
Hypothesis eq_R : equiv _ R.
Hypothesis op_assoc : forall a b c : M, R (op (op a b) c) (op a (op b c)).
Hypothesis op_neutral_left : forall a : M, R (op neutral a) a.
Hypothesis op_neutral_right : forall a : M, R (op a neutral) a.
Hypothesis
op_eq : forall a b a1 b1 : M, R a a1 -> R b b1 -> R (op a b) (op a1 b1).

(* Specifications: *)
Lemma op_eq_2 : forall a b b1 : M, R b b1 -> R (op a b) (op a b1).
Lemma my_fold_right_aapp :
forall (A : Set) (f : ad -> A -> M) (l l' : alist A),
R (fold_right (F A f) neutral (aapp _ l l'))
(op (fold_right (F A f) neutral l) (fold_right (F A f) neutral l')).
Lemma myMapFold_as_fold_1 :
forall (A : Set) (f : ad -> A -> M) (m : Map A) (pf : ad -> ad),
R (MapFold1 _ M neutral op f pf m)
(fold_right (fun (r : ad * A) (m : M) => let (a, y) := r in op (f a y) m)
neutral
(MapFold1 _ (alist A) (anil A) (aapp A)
(fun (a : ad) (y : A) => acons _ (a, y) (anil _)) pf m)).
Lemma myMapFold_as_fold :
forall (A : Set) (f : ad -> A -> M) (m : Map A),
R (MapFold _ M neutral op f m)
(fold_right (fun (r : ad * A) (m : M) => let (a, y) := r in op (f a y) m)
neutral (alist_of_Map _ m)).