(************************************************************************)
(*         *      The Rocq Prover / The Rocq Development Team           *)
(*  v      *         Copyright INRIA, CNRS and contributors             *)
(* <O___,, * (see version control and CREDITS file for authors & dates) *)
(*   \VV/  **************************************************************)
(*    //   *    This file is distributed under the terms of the         *)
(*         *     GNU Lesser General Public License Version 2.1          *)
(*         *     (see LICENSE file for the text of the license)         *)
(************************************************************************)
(* G. Huet 1-9-95 *)
Set Implicit Arguments.
Section multiset_defs.
Variable A : Type.
Variable eqA : A -> A -> Prop.
Hypothesis eqA_equiv : Equivalence eqA.
Hypothesis Aeq_dec : forall x y:A, {eqA x y} + {~ eqA x y}.
Inductive multiset : Type :=
Bag : (A -> nat) -> multiset.
Definition EmptyBag := Bag (fun a:A => 0).
Definition SingletonBag (a:A) :=
Bag (fun a':A => match Aeq_dec a a' with
| left _ => 1
| right _ => 0
end).
Definition multiplicity (m:multiset) (a:A) : nat := let (f) := m in f a.
(** multiset equality *)
Definition meq (m1 m2:multiset) :=
forall a:A, multiplicity m1 a = multiplicity m2 a.

(* Specifications: *)
Lemma meq_refl : forall x:multiset, meq x x.
Lemma meq_trans : forall x y z:multiset, meq x y -> meq y z -> meq x z.
Lemma meq_sym : forall x y:multiset, meq x y -> meq y x.
Definition munion (m1 m2:multiset) :=
Bag (fun a:A => multiplicity m1 a + multiplicity m2 a).