(**************************************************************************)
  (*                             Other Definitions                          *)
  (**************************************************************************)

  (* FA[] (Q => FA[] P) *)

  Definition ForAll_from (Sini : S) (Q P : S -> Prop) :=
    ForAll Sini (fun s : S => Q s -> ForAll s P).(* (s:S) (RState Sini s) -> (Q s) -> (ForAll s P). *)


  (* FA[] (Q => FA[](bound t) P) *)

  Definition ForAll_from_T (Sini : S) (Q P : S -> Prop)
    (bound : Instant -> Prop) :=
    ForAll Sini (fun s : S => Q s -> ForAll_T s P bound).(* (s:S) (RState Sini s) -> (Q s) -> (ForAll_T s P bound). *)

  
  (* FA[] (Q => EX<> P) *)

  Definition Exists_from (Sini : S) (Q P : S -> Prop) :=
    ForAll Sini (fun s : S => Q s -> Exists s P).(* (s:S) (RState Sini s) -> (Q s) -> (Exists s P). *)


  (* FA[] (Q => EX<>(bound t) P) *)

  Definition Exists_from_T (Sini : S) (Q P : S -> Prop)
    (bound : Instant -> Prop) :=
    ForAll Sini (fun s : S => Q s -> Exists_T s P bound).Infix "^" := Cons.(* Transitions *)
  
  Notation SPath := (Stream S) (only parsing).CoInductive ForAllS (P : Stream S -> Prop) : Stream S -> Prop :=
      forallS :
        forall (x : Stream S) (s : S),
        P (s ^ x) -> ForAllS P x -> ForAllS P (s ^ x).CoInductive ForAllS (P : Stream S -> Prop) : Stream S -> Prop :=
      forallS :
        forall (x : Stream S) (s : S),
        P (s ^ x) -> ForAllS P x -> ForAllS P (s ^ x).Inductive ExistsS (P : Stream S -> Prop) : Stream S -> Prop :=
    | Here : forall x : Stream S, P x -> ExistsS P x
    | Further :
        forall (x : Stream S) (s : S), ExistsS P x -> ExistsS P (s ^ x).Inductive ExistsS (P : Stream S -> Prop) : Stream S -> Prop :=
    | Here : forall x : Stream S, P x -> ExistsS P x
    | Further :
        forall (x : Stream S) (s : S), ExistsS P x -> ExistsS P (s ^ x).Inductive ExistsS (P : Stream S -> Prop) : Stream S -> Prop :=
    | Here : forall x : Stream S, P x -> ExistsS P x
    | Further :
        forall (x : Stream S) (s : S), ExistsS P x -> ExistsS P (s ^ x).(* Ejecution traces *)
  
  CoInductive isTrace : Stream S -> Prop :=
      is_trace :
        forall (x : Stream S) (s1 s2 : S) (l : Label),
        tr s1 l s2 -> isTrace (s2 ^ x) -> isTrace (s1 ^ s2 ^ x).(* Ejecution traces *)
  
  CoInductive isTrace : Stream S -> Prop :=
      is_trace :
        forall (x : Stream S) (s1 s2 : S) (l : Label),
        tr s1 l s2 -> isTrace (s2 ^ x) -> isTrace (s1 ^ s2 ^ x).Definition isTraceFrom (Sini : S) (x : Stream S) :=
    Sini = hd x /\ isTrace x.(* Operator Until *)

  Inductive Until (P Q : Stream S -> Prop) : Stream S -> Prop :=
    | UntilFurther :
        forall (s : S) (x : Stream S),
        P (s ^ x) -> Until P Q x -> Until P Q (s ^ x)
    | UntilHere : forall x : Stream S, Q x -> Until P Q x.(* Operator Until *)

  Inductive Until (P Q : Stream S -> Prop) : Stream S -> Prop :=
    | UntilFurther :
        forall (s : S) (x : Stream S),
        P (s ^ x) -> Until P Q x -> Until P Q (s ^ x)
    | UntilHere : forall x : Stream S, Q x -> Until P Q x.(* Operator Until *)

  Inductive Until (P Q : Stream S -> Prop) : Stream S -> Prop :=
    | UntilFurther :
        forall (s : S) (x : Stream S),
        P (s ^ x) -> Until P Q x -> Until P Q (s ^ x)
    | UntilHere : forall x : Stream S, Q x -> Until P Q x.Inductive EX_Until (Sini : S) (P Q : Stream S -> Prop) : Prop :=
      ExUntil :
        forall x : Stream S,
        isTraceFrom Sini x -> Until P Q x -> EX_Until Sini P Q.Inductive EX_Until (Sini : S) (P Q : Stream S -> Prop) : Prop :=
      ExUntil :
        forall x : Stream S,
        isTraceFrom Sini x -> Until P Q x -> EX_Until Sini P Q.Definition FA_Until (Sini : S) (P Q : Stream S -> Prop) :=
    forall x : Stream S, isTraceFrom Sini x -> Until P Q x.(* Init => FA[] P *)

  Definition Always (Sini : S) (P : Stream S -> Prop) :=
    forall x : Stream S, isTraceFrom Sini x -> ForAllS P x.(* Init => FA<> P *)

  Definition Inevitable (Sini : S) (P : Stream S -> Prop) :=
    forall x : Stream S, isTraceFrom Sini x -> ExistsS P x.(* Init => EX<> P *)

  Inductive Posible (Sini : S) (P : Stream S -> Prop) : Prop :=
      posible :
        forall x : Stream S,
        isTraceFrom Sini x -> ExistsS P x -> Posible Sini P.(* Init => EX<> P *)

  Inductive Posible (Sini : S) (P : Stream S -> Prop) : Prop :=
      posible :
        forall x : Stream S,
        isTraceFrom Sini x -> ExistsS P x -> Posible Sini P.(* Init => EX[] P *)

  Inductive SafePath (Sini : S) (P : Stream S -> Prop) : Prop :=
      safePath :
        forall x : Stream S,
        isTraceFrom Sini x -> ForAllS P x -> SafePath Sini P.(* Init => EX[] P *)

  Inductive SafePath (Sini : S) (P : Stream S -> Prop) : Prop :=
      safePath :
        forall x : Stream S,
        isTraceFrom Sini x -> ForAllS P x -> SafePath Sini P.

Theorem Mon_I_S : forall (x : Stream S) (Pg Pp : Stream S -> Prop), ForAllS Pg x -> (forall s : Stream S, Pg s -> Pp s) -> ForAllS Pp x.