(** reduce remove from h all the redundancy: a pair (M,N) is kept
   in (reduce h) iff it cannot be 'strictly' synthetised by h *)
Definition reduce (h : hedge) (M N : Msg) :=
  h M N /\
  match M with
  | MEnc M' K =>
      match N with
      | MEnc N' L => ~ synthesis h M' N' \/ ~ synthesis h K L
      | _ => True
      end
  | MPair M1 M2 =>
      match N with
      | MPair N1 N2 => ~ synthesis h M1 N1 \/ ~ synthesis h M2 N2
      | _ => True
      end
  | Mop opM M' =>
      match N with
      | Mop opN N' => opM <> opN \/ ~ synthesis h M' N'
      | _ => True
      end
  | _ => True
  end.

(* Specifications: *)
Lemma red_incl_h : forall h : hedge, inclusion (reduce h) h.
Lemma h_le_h_red : forall h : hedge, le_h h (reduce h).
Lemma h_equiv_h_red : forall h : hedge, equiv_h h (reduce h).
Lemma inclusion_le_h_reduce_inclusion : forall g h : hedge, inclusion g h -> le_h h g -> inclusion (reduce g) (reduce h).
Lemma equal_reduce_equal : forall g h : hedge, equal g h -> equal (reduce g) (reduce h).
Lemma inclusion_le_h_impl_inclusion_red : forall g h : hedge, inclusion (reduce g) h -> le_h h (reduce g) -> inclusion (reduce g) (reduce h).
Lemma reduce_idempotent : forall h : hedge, equal (reduce h) (reduce (reduce h)).
Lemma red_equiv_impl_red_incl : forall g h : hedge, equiv_h (reduce g) h -> inclusion (reduce g) h.
Lemma red_stable_le_h : forall g h : hedge, le_h g h -> le_h (reduce g) (reduce h).