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 Conj_S :
forall (x : Stream S) (P1 P2 : Stream S -> Prop),
ForAllS P1 x ->
ForAllS P2 x -> ForAllS (fun s : Stream S => P1 s /\ P2 s) x.