Section FreeGroups.
Variable generators: Type.
Hypothesis generator_eq_dec: forall g1 g2:generators,
{ g1=g2 } + { g1<>g2 }.
Inductive alphabet: Type :=
| intro_gen: generators -> alphabet
| intro_gen_inv: generators -> alphabet.
Definition group_str := list alphabet.
Definition opposite (letter:alphabet) :=
match letter with
| intro_gen a => intro_gen_inv a
| intro_gen_inv a => intro_gen a
end.
Inductive non_reduced: group_str -> Prop :=
| intro_letter_inverse: forall (S T: group_str) (a: alphabet),
non_reduced (S ++ (opposite a) :: a :: T).
Definition reduced (S: group_str) : Prop :=
not (non_reduced S).
Definition alphabet_eq_dec: forall a b:alphabet,
{a=b} + {a<>b}.
intros.
decide equality.
Qed.
(* define the left action of each letter on the set of reduced words *)
Definition letter_action (a:alphabet) (S:group_str) : group_str :=
match S with
| nil => a :: nil
| b :: S0 => (if alphabet_eq_dec a (opposite b) then S0
else a :: b :: S0)
end.
Fixpoint group_str_action (S T:group_str) :=
match S with
| nil => T
| a :: S0 => letter_action a (group_str_action S0 T)
end.
Definition reduction (S:group_str) :=
group_str_action S nil.

Lemma reduction_is_reduced: forall S:group_str, reduced (reduction S).