(* 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                                                     *)
Set Automatic Coercions Import.
Set Implicit Arguments.
Unset Strict Implicit.
Require Export Module_util.
Require Export Module_facts.
Section Free_Module_def.
Variable R : RING.
Variable V : SET.
Inductive FMd : Type :=
| Var : V -> FMd
| Law : FMd -> FMd -> FMd
| Unit : FMd
| Inv : FMd -> FMd
| Op : R -> FMd -> FMd.
Inductive eqFMd : FMd -> FMd -> Prop :=
| eqFMd_Var : forall x y : V, Equal x y -> (eqFMd (Var x) (Var y):Prop)
| eqFMd_law :
forall x x' y y' : FMd,
eqFMd x x' -> eqFMd y y' -> (eqFMd (Law x y) (Law x' y'):Prop)
| eqFMd_law_assoc :
forall x y z : FMd, eqFMd (Law (Law x y) z) (Law x (Law y z)):Prop
| eqFMd_law0r : forall x : FMd, eqFMd (Law x Unit) x:Prop
| eqFMd_inv : forall x y : FMd, eqFMd x y -> eqFMd (Inv x) (Inv y)
| eqFMd_invr : forall x : FMd, eqFMd (Law x (Inv x)) Unit
| eqFMd_refl : forall x : FMd, eqFMd x x:Prop
| eqFMd_sym : forall x y : FMd, eqFMd x y -> (eqFMd y x:Prop)
| eqFMd_trans :
forall x y z : FMd, eqFMd x y -> eqFMd y z -> (eqFMd x z:Prop)
| eqFMd_com : forall x y : FMd, eqFMd (Law x y) (Law y x)
| eqFMd_op_comp :
forall (a b : R) (x y : FMd),
Equal a b -> eqFMd x y -> (eqFMd (Op a x) (Op b y):Prop)
| eqFMd_oplin_l :
forall (a b : R) (x : FMd),
eqFMd (Op (sgroup_law R a b) x) (Law (Op a x) (Op b x))
| eqFMd_oplin_r :
forall (a : R) (x y : FMd),
eqFMd (Op a (Law x y)) (Law (Op a x) (Op a y))
| eqFMd_op_assoc :
forall (a b : R) (x : FMd),
eqFMd (Op a (Op b x)) (Op (ring_mult a b) x)
| eqFMd_op_unit : forall x : FMd, eqFMd (Op (ring_unit R) x) x.
Hint Resolve eqFMd_Var eqFMd_law eqFMd_law_assoc eqFMd_law0r eqFMd_invr
eqFMd_refl: algebra.
Hint Immediate eqFMd_sym: algebra.

Lemma eqFMd_Equiv : equivalence eqFMd.
red in |- *.