(** 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).
Theorem inj_inv_left_syn : forall h : hedge, injective_left h -> enc_synthesis_left h -> op_synthesis_left h -> pair_free_left h -> injective_inv_left h -> injective_inv_left (synthesis h).