(* This program is free software; you can redistribute it and/or      *)
(* modify it under the terms of the GNU Lesser General Public License *)
(* as published by the Free Software Foundation; either version 2.1   *)
(* of the License, or (at your option) any later version.             *)
(*                                                                    *)
(* This program is distributed in the hope that it will be useful,    *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of     *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *)
(* GNU General Public License for more details.                       *)
(*                                                                    *)
(* You should have received a copy of the GNU Lesser General Public   *)
(* License along with this program; if not, write to the Free         *)
(* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *)
(* 02110-1301 USA                                                     *)
Set Implicit Arguments.
Unset Strict Implicit.
Require Export Streams.
Infix "^" := Cons.
Section TemporalOperators_CTL.
(*** operators CTL with co-inductives types: definitions and properties ***)
Variable Label : Set.               (* labels: dicrete transitions *)
Variable S : Set.               (* states                      *)
Variable tr : S -> Label -> S -> Prop. (* transitions                 *)
Variable inv : S -> Prop.         (* location invariants         *)
Variable inc : S -> Instant -> S. (* increase clocks of states   *)
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 :=
| isTraceTick :
forall (x : Stream S) (s : S),
inv (inc s tick) ->
isTrace (inc s tick ^ x) -> isTrace (s ^ inc s tick ^ x)
| isTraceDisc :
forall (x : Stream S) (s1 s2 : S) (l : Label),
tr s1 l s2 -> inv 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).