(** On the other hand, the corresponding elimination scheme does not
    hold, due to the existence of inhabitants of the type (opt X)
    that are neither of the form (some X x) nor of the form (none X),
    such as the term  [f:X->Prop]top : (opt X)  for instance.

    In practice, the existence of such parasitic elements will not
    pose a problem.  When defining edge relations on data-types such
    as (opt X), we will simply ignore these extra elements so that
    they will become invisible up to a bisimulation. *)

(** ** Extended sum type **)

(** The (extended) sum type (sum X Y) : Typ1 (parametrized by the
    types X,Y : Typ1) that would be inductively defined in Coq by

      Inductive sum [X,Y:Typ1] : Typ1 :=
      | inl : X->(sum X Y)                  (left injection)
      | inr : Y->(sum X Y)                  (right injection)
      | out : (sum X Y).                    (extra element)

    is mimicked by the following definitions: *)

Definition sum (X Y : Typ1) : Typ1 := (X -> Prop) -> (Y -> Prop) -> Prop.Definition inl (X Y : Typ1) (x : X) : sum X Y := fun f _ => f x.Definition inr (X Y : Typ1) (y : Y) : sum X Y := fun _ g => g y.Definition out (X Y : Typ1) : sum X Y := fun _ _ => bot.

(* Specifications: *)
Lemma eq_inl_inl : forall (X Y : Typ1) (x1 x2 : X), eq (sum X Y) (inl X Y x1) (inl X Y x2) -> eq X x1 x2.
Lemma eq_inr_inr : forall (X Y : Typ1) (y1 y2 : Y), eq (sum X Y) (inr X Y y1) (inr X Y y2) -> eq Y y1 y2.
Lemma eq_inl_inr : forall (X Y : Typ1) (x : X) (y : Y), eq (sum X Y) (inl X Y x) (inr X Y y) -> bot.
Lemma eq_inr_inl : forall (X Y : Typ1) (x : X) (y : Y), eq (sum X Y) (inr X Y y) (inl X Y x) -> bot.
Lemma eq_inl_out : forall (X Y : Typ1) (x : X), eq (sum X Y) (inl X Y x) (out X Y) -> bot.
Lemma eq_out_inl : forall (X Y : Typ1) (x : X), eq (sum X Y) (out X Y) (inl X Y x) -> bot.
Lemma eq_inr_out : forall (X Y : Typ1) (y : Y), eq (sum X Y) (inr X Y y) (out X Y) -> bot.
Lemma eq_out_inr : forall (X Y : Typ1) (y : Y), eq (sum X Y) (out X Y) (inr X Y y) -> bot.