split; [ try assumption | idtac ].
exact eqFaM_refl.
red in |- *.
split; [ try assumption | idtac ].
exact eqFaM_trans.
exact eqFaM_sym.
Qed.
Definition FaM_set := Build_Setoid eqFaM_Equiv.
Definition FreeAbelianMonoid : ABELIAN_MONOID.
apply (BUILD_ABELIAN_MONOID (E:=FaM_set) (genlaw:=Law) (e:=Unit)).
exact eqFaM_law.
exact eqFaM_law_assoc.
exact eqFaM_law0r.
exact eqFaM_law0l.
exact eqFaM_com.
Defined.
Section Universal_prop.
Variable M : ABELIAN_MONOID.
Variable f : Hom V M.
Fixpoint FaM_lift_fun (p : FreeAbelianMonoid) : M :=
match p with
| Var v => f v
| Law p1 p2 => sgroup_law _ (FaM_lift_fun p1) (FaM_lift_fun p2)
| Unit => monoid_unit M
end.
Definition FaM_lift : Hom FreeAbelianMonoid M.
apply (BUILD_HOM_MONOID (G:=FreeAbelianMonoid) (G':=M) (ff:=FaM_lift_fun)).
intros x y H'; try assumption.
elim H'; simpl in |- *; auto with algebra.
intros x0 y0 z H'0 H'1 H'2 H'3; try assumption.
apply Trans with (FaM_lift_fun y0); auto with algebra.
simpl in |- *; auto with algebra.
simpl in |- *; auto with algebra.
Defined.
Definition FaM_var : Hom V FreeAbelianMonoid.
apply (Build_Map (A:=V) (B:=FreeAbelianMonoid) (Ap:=Var)).
red in |- *.
simpl in |- *; auto with algebra.
Defined.

(* Specifications: *)
Lemma FaM_comp_prop :
Equal f (comp_hom (FaM_lift:Hom (FreeAbelianMonoid:SET) M) FaM_var).