(* Location invariants *)
 
  Notation State_T := (S * Instant)%type (only parsing).Notation SPath_T := (Stream (S * Instant)) (only parsing).(* Ejecution traces *)

  CoInductive isTrace_T : Stream (S * Instant) -> Prop :=
    | isTraceTick :
        forall (x : Stream (S * Instant)) (s1 s2 : S) (t : Instant),
        tr s1 Tick s2 ->
        isTrace_T ((s2, Inc t) ^ x) -> isTrace_T ((s1, t) ^ (s2, Inc t) ^ x)
    | isTraceDisc :
        forall (x : Stream (S * Instant)) (s1 s2 : S) 
          (t : Instant) (l : Label),
        tr s1 l s2 ->
        l <> Tick ->
        isTrace_T ((s2, t) ^ x) -> isTrace_T ((s1, t) ^ (s2, t) ^ x).(* Ejecution traces *)

  CoInductive isTrace_T : Stream (S * Instant) -> Prop :=
    | isTraceTick :
        forall (x : Stream (S * Instant)) (s1 s2 : S) (t : Instant),
        tr s1 Tick s2 ->
        isTrace_T ((s2, Inc t) ^ x) -> isTrace_T ((s1, t) ^ (s2, Inc t) ^ x)
    | isTraceDisc :
        forall (x : Stream (S * Instant)) (s1 s2 : S) 
          (t : Instant) (l : Label),
        tr s1 l s2 ->
        l <> Tick ->
        isTrace_T ((s2, t) ^ x) -> isTrace_T ((s1, t) ^ (s2, t) ^ x).(* Ejecution traces *)

  CoInductive isTrace_T : Stream (S * Instant) -> Prop :=
    | isTraceTick :
        forall (x : Stream (S * Instant)) (s1 s2 : S) (t : Instant),
        tr s1 Tick s2 ->
        isTrace_T ((s2, Inc t) ^ x) -> isTrace_T ((s1, t) ^ (s2, Inc t) ^ x)
    | isTraceDisc :
        forall (x : Stream (S * Instant)) (s1 s2 : S) 
          (t : Instant) (l : Label),
        tr s1 l s2 ->
        l <> Tick ->
        isTrace_T ((s2, t) ^ x) -> isTrace_T ((s1, t) ^ (s2, t) ^ x).Definition isTraceFrom_T (Sini : S * Instant) (x : Stream (S * Instant)) :=
    Sini = hd x /\ isTrace_T x.(* Until operator *)

  Inductive Until_bound (P Q : Stream (S * Instant) -> Prop) :
  Stream (S * Instant) -> Prop :=
    | UntilFurther_bound :
        forall (s : S * Instant) (x : Stream (S * Instant)),
        P (s ^ x) -> Until_bound P Q x -> Until_bound P Q (s ^ x)
    | UntilHere_bound :
        forall (s : S) (t : Instant) (x : Stream (S * Instant)),
        bound t -> Q ((s, t) ^ x) -> Until_bound P Q ((s, t) ^ x).(* Until operator *)

  Inductive Until_bound (P Q : Stream (S * Instant) -> Prop) :
  Stream (S * Instant) -> Prop :=
    | UntilFurther_bound :
        forall (s : S * Instant) (x : Stream (S * Instant)),
        P (s ^ x) -> Until_bound P Q x -> Until_bound P Q (s ^ x)
    | UntilHere_bound :
        forall (s : S) (t : Instant) (x : Stream (S * Instant)),
        bound t -> Q ((s, t) ^ x) -> Until_bound P Q ((s, t) ^ x).(* Until operator *)

  Inductive Until_bound (P Q : Stream (S * Instant) -> Prop) :
  Stream (S * Instant) -> Prop :=
    | UntilFurther_bound :
        forall (s : S * Instant) (x : Stream (S * Instant)),
        P (s ^ x) -> Until_bound P Q x -> Until_bound P Q (s ^ x)
    | UntilHere_bound :
        forall (s : S) (t : Instant) (x : Stream (S * Instant)),
        bound t -> Q ((s, t) ^ x) -> Until_bound P Q ((s, t) ^ x).Inductive EX_Until_bound (Sini : S * Instant)
  (P Q : Stream (S * Instant) -> Prop) : Prop :=
      ExUntil_bound :
        forall x : Stream (S * Instant),
        isTraceFrom_T Sini x -> Until_bound P Q x -> EX_Until_bound Sini P Q.Inductive EX_Until_bound (Sini : S * Instant)
  (P Q : Stream (S * Instant) -> Prop) : Prop :=
      ExUntil_bound :
        forall x : Stream (S * Instant),
        isTraceFrom_T Sini x -> Until_bound P Q x -> EX_Until_bound Sini P Q.Definition FA_Until_bound (Sini : S * Instant)
    (P Q : Stream (S * Instant) -> Prop) :=
    forall x : Stream (S * Instant),
    isTraceFrom_T Sini x -> Until_bound P Q x.(* Init => FA[](bound t) P *)

  Definition Always_T (Sini : S * Instant)
    (P : Stream (S * Instant) -> Prop) :=
    forall x : Stream (S * Instant),
    isTraceFrom_T Sini x ->
    ForAllS (fun s : Stream (S * Instant) => bound (snd (hd s)) -> P s) x.(* Init => FA<>(bound t) P *)

  Definition Inevitable_T (Sini : S * Instant)
    (P : Stream (S * Instant) -> Prop) :=
    forall x : Stream (S * Instant),
    isTraceFrom_T Sini x ->
    ExistsS (fun s : Stream (S * Instant) => bound (snd (hd s)) /\ P s) x.(* Init => EX<>(bound t) P *)

  Inductive Posible_T (Sini : S * Instant) (P : Stream (S * Instant) -> Prop)
  : Prop :=
      posible_T :
        forall x : Stream (S * Instant),
        isTraceFrom_T Sini x ->
        ExistsS (fun s : Stream (S * Instant) => bound (snd (hd s)) /\ P s) x ->
        Posible_T Sini P.(* Init => EX<>(bound t) P *)

  Inductive Posible_T (Sini : S * Instant) (P : Stream (S * Instant) -> Prop)
  : Prop :=
      posible_T :
        forall x : Stream (S * Instant),
        isTraceFrom_T Sini x ->
        ExistsS (fun s : Stream (S * Instant) => bound (snd (hd s)) /\ P s) x ->
        Posible_T Sini P.(* Init => EX[](bound t) P *)

  Inductive SafePath_T (Sini : S * Instant)
  (P : Stream (S * Instant) -> Prop) : Prop :=
      safePath_T :
        forall x : Stream (S * Instant),
        isTraceFrom_T Sini x ->
        ForAllS (fun s : Stream (S * Instant) => bound (snd (hd s)) -> P s) x ->
        SafePath_T Sini P.(* Init => EX[](bound t) P *)

  Inductive SafePath_T (Sini : S * Instant)
  (P : Stream (S * Instant) -> Prop) : Prop :=
      safePath_T :
        forall x : Stream (S * Instant),
        isTraceFrom_T Sini x ->
        ForAllS (fun s : Stream (S * Instant) => bound (snd (hd s)) -> P s) x ->
        SafePath_T Sini P.

(* Specifications: *)
Theorem Equiv1_T : forall (Sini : S * Instant) (P : Stream (S * Instant) -> Prop), Posible_T Sini P <-> EX_Until_bound Sini (fun _ : Stream (S * Instant) => True) P.
Theorem Equiv2_T : forall (Sini : S * Instant) (P : Stream (S * Instant) -> Prop), Inevitable_T Sini P <-> FA_Until_bound Sini (fun _ : Stream (S * Instant) => True) P.
Lemma ConsTrace_T : forall (s1 s2 : S * Instant) (x z : Stream (S * Instant)), isTraceFrom_T s2 z -> isTraceFrom_T s1 (s1 ^ s2 ^ x) -> isTraceFrom_T s1 (s1 ^ z).
Lemma notPosible_T : forall (P : Stream (S * Instant) -> Prop) (s1 : S * Instant), ~ Posible_T s1 P -> forall (z : Stream (S * Instant)) (s2 : S * Instant), isTraceFrom_T s1 (s1 ^ s2 ^ z) -> ~ Posible_T s2 P.
Theorem Equiv3_T : forall (Sini : S * Instant) (P : Stream (S * Instant) -> Prop), Always_T Sini P <-> ~ Posible_T Sini (fun s : Stream (S * Instant) => ~ P s).
Theorem Equiv4_T : forall (Sini : S * Instant) (P : Stream (S * Instant) -> Prop), SafePath_T Sini P <-> ~ Inevitable_T Sini (fun s : Stream (S * Instant) => ~ P s).