(**************************************************************************)
(*                             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).
(* (s:S) (RState Sini s) -> (Q s) -> (Exists_T s P bound). *)
End TemporalOperators_Ind.
Infix "^" := Cons.
Section TemporalOperators_CTL.
(* CTL operators with co-inductives types: definitions and properties *)
Variable S : Set.                (* States *)
Variable tr : S -> Label -> S -> Prop.  (* 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).
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).
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.
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 SafePath (Sini : S) (P : Stream S -> Prop) : Prop :=
safePath :
forall x : Stream S,
isTraceFrom Sini x -> ForAllS P x -> SafePath Sini P.
(**************************************************************************)
(*                            Some Properties                             *)
(**************************************************************************)

Theorem Equiv4 :
forall (Sini : S) (P : Stream S -> Prop),
SafePath Sini P <-> ~ Inevitable Sini (fun s : Stream S => ~ P s).