(** * General setting for behavioural equivalences *)
Require Export Functions.
Require Export Reductions.
Set Implicit Arguments.
Section Global.
Variable A: Type.
Section Sim.
Variables X Y: Type.
Variable TX: reduction_t A X.
Variable TY: reduction_t A Y.
(** More or less generic evolution predicates (Definitions 1.2)  *)
Definition evolve_1 l R S := diagram (TX l) R (Weak TY l) S.
Definition evolve_t   R S := evolve_1 (T A) R S.
Definition evolve_a   R S := forall a, evolve_1 (L a) R S .
Definition evolve     R S := forall l, evolve_1 l R S.
(** (Silent) simulation, expansion (Definitions 1.3) *)
Definition simulation_t R := evolve_t R R.
Definition simulation   R := evolve   R R.
(** (Relaxed) expansion  (on one side only) *)
Definition expansion1   R := diagram_r TX R (EWeak TY) R.
Definition wexpansion1  R := diagram_r TX R (REWeak TY) R.
Variable F: function X Y.
(** Monotonicity: Definition 1.5 *)
Record monotonic: Prop := mkmon {
mon_m:> increasing F;
mon_t:  forall R S, evolve_t R S -> incl R S -> evolve_t (F R) (F S);
mon_a:  forall R S, evolve   R S -> incl R S -> evolve_a (F R) (F S)
}.
(** Weak monotonicity: Definition 2.1 *)
Record wmonotonic: Prop := mkwmon {
wmon_m:> increasing F;
wmon_t:  forall R, simulation_t R -> simulation_t (F R);
wmon_a:  forall R S, simulation_t R -> simulation_t S -> evolve_a R S -> incl R S -> evolve_a (F R) (F S)
}.
(** Controlled relations: Definition 3.1 *)
Variable B: relation X.
Record controlled: Prop := mkctrl {
ctrl_t:  forall R, evolve_t R (comp (star B) R) -> simulation_t (comp (star B) R);
ctrl_a:  forall R S, evolve_t R (comp (star B) R) -> simulation_t S ->
evolve_a R S -> incl R S -> evolve_a (comp (star B) R) (comp (star B) S)
}.

(* Specifications: *)
(** Lemma 1.4 (1) *)
Lemma weak_strong_t: forall R, simulation_t R -> diagram (Weak TX (T A)) R (Weak TY (T A)) R.
Lemma weak_strong: forall R, simulation R -> diagram_r (Weak TX) R (Weak TY) R.
(** Lemma 1.4 (2) (splitted into several practical results) *)
Lemma union2_evolve: forall l R R' S, evolve_1 l R S -> evolve_1 l R' S -> evolve_1 l (union2 R R') S.
Lemma union2_evolve_left: forall l R S S', evolve_1 l R S -> evolve_1 l R (union2 S S').
Lemma union2_evolve_right: forall l R S S', evolve_1 l R S' -> evolve_1 l R (union2 S S').
Lemma union_evolve: forall l I R S,
(forall i:I, evolve_1 l (R i) S) -> evolve_1 l (union R) S.
Lemma evolve_union: forall l J R S,
(exists j:J, evolve_1 l R (S j)) -> evolve_1 l R (union S).
(** Evolutions behave like functional arrows (contra/co-variance) *)
Lemma incl_evolve: forall l R R' S, incl R R' -> evolve_1 l R' S -> evolve_1 l R S.
Lemma evolve_incl: forall l S R S', incl S S' -> evolve_1 l R S -> evolve_1 l R S'.
(** (Silent) simulations are insensitive to extensional equality *)
Lemma simulation_eeq: forall R S, eeq R S -> simulation R -> simulation S.
Lemma simulation_t_eeq: forall R S, eeq R S -> simulation_t R -> simulation_t S.
End Sim.