split; [ try assumption | idtac ].
exact eqFM_refl.
red in |- *.
split; [ try assumption | idtac ].
exact eqFM_trans.
exact eqFM_sym.
Qed.
Definition FM_set := Build_Setoid eqFM_Equiv.
Definition FreeMonoid : MONOID.
apply (BUILD_MONOID (E:=FM_set) (genlaw:=Law) (e:=Unit)).
exact eqFM_law.
exact eqFM_law_assoc.
exact eqFM_law0r.
exact eqFM_law0l.
Defined.
Section Universal_prop.
Variable M : MONOID.
Variable f : Hom V M.
Fixpoint FM_lift_fun (p : FreeMonoid) : M :=
match p with
| Var v => f v
| Law p1 p2 => sgroup_law _ (FM_lift_fun p1) (FM_lift_fun p2)
| Unit => monoid_unit M
end.
Definition FM_lift : Hom FreeMonoid M.
apply (BUILD_HOM_MONOID (G:=FreeMonoid) (G':=M) (ff:=FM_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 (FM_lift_fun y0); auto with algebra.
simpl in |- *; auto with algebra.
simpl in |- *; auto with algebra.
Defined.
Definition FM_var : Hom V FreeMonoid.
apply (Build_Map (A:=V) (B:=FreeMonoid) (Ap:=Var)).
red in |- *.
simpl in |- *; auto with algebra.
Defined.

(* Specifications: *)
Lemma FM_comp_prop :
Equal f (comp_hom (FM_lift:Hom (FreeMonoid:SET) M) FM_var).