intros.
apply equiv_irr_irr_impl_equal; try apply irreducible_is_irreducible.
unfold equiv_h in |- *.
split.
apply le_h_trans with (irreducible (irreducible (union h g))).
apply le_h_irr_le_h.
apply le_h_le_h_impl_union_le_h.
apply le_h_irr_le_h.
apply inclusion_impl_le_h.
apply hedge_left_union.
apply le_h_trans with (irreducible g).
apply h_le_h_irr_h.
apply le_h_irr_le_h.
apply inclusion_impl_le_h.
apply hedge_right_union.
generalize (irreducible_is_irreducible (union h g)).
unfold is_irreducible in |- *.
unfold equal in |- *.
intros.
apply inclusion_impl_le_h.
tauto.
apply le_h_irr_le_h.
apply le_h_le_h_impl_le_h_union.
apply h_le_h_irr_h.
apply le_h_refl.
Qed.
(** we define afterwards the notion of left consistency: we define first several predicates on hedges *)
(** if (M,N) is in h and M is a name then N is a name *)
Definition name_left_name (h : hedge) :=
forall M N : Msg,
h M N -> forall a : Nam, M = MNam a -> exists b : Nam, N = MNam b.
(** if (M,N) and (M',N') are in h and M = M' then N = N' *)
Definition injective_left (h : hedge) :=
forall M N : Msg, h M N -> forall M' N' : Msg, h M' N' -> M = M' -> N = N'.
(** if op(M) is in the left projection of h then M is not in the left projection of S(h) *)
Definition op_synthesis_left (h : hedge) :=
forall (o : op) (M N : Msg),
h M N ->
forall M' : Msg, M = Mop o M' -> forall N' : Msg, ~ synthesis h M' N'.
(** if {M}K is in the left projection of h then either M or K are not in the left projection of S(h) *)
Definition enc_synthesis_left (h : hedge) :=
forall M N : Msg,
h M N ->
forall M' K : Msg,
M = MEnc M' K ->
forall N' L : Msg, ~ synthesis h M' N' \/ ~ synthesis h K L.
(** the left projection of h does not contain any pair *)
Definition pair_free_left (h : hedge) :=
forall M1 M2 N : Msg, ~ h (MPair M1 M2) N.
(** if ({M}K,N') is in h and (inv K) is in the left projection of S(h) then N' = {N}L, (inv K,inv L) is in S(h) and (M,N) is in S(h) *)
Definition enc_analysis_left (h : hedge) :=
forall M N : Msg,
h M N ->
forall M' K : Msg,
M = MEnc M' K ->
forall L : Msg,
synthesis h (inv K) (inv L) ->
exists N' : Msg, N = MEnc N' L /\ synthesis h M' N'.
(** if (M,N) is in h and (inv M,N') is in h then N'=(inv N) *)
Definition injective_inv_left (h : hedge) :=
forall M N : Msg,
h M N -> forall M' N' : Msg, h M' N' -> M' = inv M -> N' = inv N.
(** left consistency of h *)
Definition is_left_consistent (h : hedge) : Prop :=
name_left_name h /\
injective_left h /\
op_synthesis_left h /\
pair_free_left h /\
enc_synthesis_left h /\ enc_analysis_left h /\ injective_inv_left h.
Definition weak_left_consistent (h : hedge) :=
name_left_name h /\
injective_left h /\
op_synthesis_left h /\
pair_free_left h /\ enc_synthesis_left h /\ enc_analysis_left h.

(* Specifications: *)
Theorem inj_left_syn :
forall h : hedge,
injective_left h ->
enc_synthesis_left h ->
op_synthesis_left h -> pair_free_left h -> injective_left (synthesis h).