Section sec_modal_op_lemmas.
Variable T : Type.
Proof using.
now destruct ex.
Qed.
(* always facts *)
Proof using.
intros P invP.
cofix c.
intros [x s] Pxs; apply Always; trivial.
apply c; apply invP in Pxs.
assumption.
Qed.
Proof using.
intros x s P al. change (P (Cons x s) /\ always P (tl (Cons x s))).
destruct al. split; assumption.
Qed.
Proof using.
intros x s P al. case (always_Cons x s P al); trivial.
Qed.
Proof using.
destruct ex.
apply always_now.
Qed.
Proof using.
intros x s P al. case (always_Cons x s P al); trivial.
Qed.
Proof using.
intros (x, s). simpl. apply always_invar.
Qed.
Proof using.
cofix c.
intros [x s].
apply Always.
- unfold not_tl, False_tl; auto.
- apply c.
Qed.
Proof using.
cofix c.
intros [x s].
apply Always.
- unfold True_tl; trivial.
- apply c.
Qed.
Proof using.
intros P Q.
cofix c.
intros s alP alQ.
destruct alP.
destruct alQ.
apply Always.
- split; assumption.
- apply c; assumption.
Qed.
Proof using.
intro P.
cofix c.
constructor.
- auto.
- do 2 destruct s.
constructor; eauto using always_invar.
Qed.
Proof using.
intros P.
cofix alwn.
intros s a; case a; clear a s. intros (x, s); simpl. constructor.
- assumption.
- apply alwn; assumption.
Qed.
Proof using.
intros P.
cofix alwn. destruct 1. constructor; simpl.
- assumption.
- apply alwn; assumption.
Qed.
Proof using.
intros J P.
cofix c.
intros [x s] alJ.
apply W_tl.
- apply always_now in alJ.
assumption.
- apply c.
apply always_invar in alJ.
assumption.
Qed.
Proof using.
intros J P.
cofix c.
intros [x s] al.
apply R_tl.
- apply always_now in al.
assumption.
- simpl.
apply c.
apply always_invar in al.
assumption.
Qed.
Proof using.
intros P. cofix f. intros s a. destruct a. constructor.
- constructor 1. assumption.
- apply f. assumption.
Qed.
Proof using.
intros P s alP.
apply E0.
assumption.
Qed.
(* weak_until and eventually facts *)
Proof using.
intros x s J P un.
change (P (Cons x s) \/ (J (Cons x s) /\ weak_until J P (tl (Cons x s)))).
destruct un; intuition.
Qed.
Proof using.
cofix cf.
intros J J' P s Hweak Halways.
destruct s.
inversion Hweak.
- now eauto using W0.
- inversion Halways.
eapply W_tl.
+ now unfold and_tl.
+ simpl. now eauto.
Qed.
Proof using.
intros J P s un.
induction un.
- apply W0. assumption.
- apply W_tl; trivial.
Qed.
Proof using.
intros x s P al. change (P (Cons x s) \/ eventually P (tl (Cons x s))). case al; auto.
Qed.
Proof using.
intros P Q inv is_inv PeQ s invs ev. induction ev as [s Ps | x s ev IHev].
- apply PeQ; assumption.
- constructor 2. apply IHev. apply is_inv with x; assumption.
Qed.
Proof using.
intros P x s evCP evP.
contradict evCP.
apply E_next.
assumption.
Qed.
Proof using.
intros e P ev. induction ev as [(x, s) Ps | x s ev induc_hyp].
- constructor 2; constructor 1; exact Ps.
- constructor 2. apply induc_hyp.
Qed.
Proof using.
induction 1 as [s Ps | x s evPs induc_hyp]; intro al.
- constructor 1. split; assumption.
- constructor 2. apply induc_hyp. eapply always_invar; eauto.
Qed.
Proof using.
intros s P J ev. induction ev as [s Ps | x s evPs induc_hyp].
- intro un. constructor 1. split; assumption.
- intro unxs. case (weak_until_Cons _ _ _ _ unxs).
* intro Pxs. constructor 1; split; assumption.
* intros (_, uns). constructor 2. apply induc_hyp. exact uns.
Qed.
Proof using.
intros P Q J impl s Js J_weak_until_Q ev.
genclear J_weak_until_Q; genclear Js.
induction ev as [s Ps | x s ev induc_hyp].
- intros Js J_weak_until_Q. constructor 1. apply impl; assumption.
- intros _ J_weak_until_Q. cut (s = tl (Cons x s)); [idtac | reflexivity].
case J_weak_until_Q; clear J_weak_until_Q x.
* constructor 1; assumption.
* intros (x, s1) _ J_weak_until_Q e; simpl in *.
constructor 2. generalize e J_weak_until_Q; clear e x. (* trick: keep J_weak_until_Q!! *)
case J_weak_until_Q; clear J_weak_until_Q s1.
+ clearall. constructor 1; assumption.
+ intros s2 Js2 _ e J_weak_until_Q2. rewrite e in induc_hyp; clear e.
apply induc_hyp; assumption.
Qed.
Proof using.
induction 1; firstorder using E0, E_next.
Qed.
Proof using.
induction 1; firstorder using E0, E_next.
Qed.
Proof using.
induction 1; firstorder using E0, E_next.
Qed.
(* until facts *)
Proof using.
intros x s J P ul.
change (P (Cons x s) \/ (J (Cons x s) /\ until J P (tl (Cons x s)))). case ul; auto.
Qed.
Proof using.
intros P J s unP.
induction unP.
- apply E0; assumption.
- apply E_next; assumption.
Qed.
(* release facts *)
Proof using.
intros x s J P rl.
change (P (Cons x s) /\ (J (Cons x s) \/ release J P (tl (Cons x s)))).
destruct rl; intuition.
Qed.
(* inf_often and continuously facts *)
Proof using.
intros x s P; apply always_invar.
Qed.
Proof using.
intros x s P cny.
apply eventually_Cons in cny.
case cny; trivial.
intro alP.
apply E0.
apply always_invar in alP; assumption.
Qed.
Proof using.
intros P Q s cnyP.
induction cnyP as [s alP|].
- intro cnyQ.
induction cnyQ.
apply E0.
apply always_and_tl; trivial.
apply E_next.
apply IHcnyQ.
apply always_invar in alP; assumption.
- intro cnyQ.
apply E_next.
apply IHcnyP.
apply continuously_invar in cnyQ; assumption.
Qed.
Proof using.
intros P.
cofix c.
intros s cnyP.
induction cnyP.
- apply always_inf_often. assumption.
- apply Always.
* apply E_next. destruct s as [s x']. apply always_now in IHcnyP. assumption.
* apply IHcnyP.
Qed.
(* monotony *)
Proof using.
intros P Q PQ (x, s) nP; simpl. apply PQ. assumption.
Qed.
Proof using.
intros P Q PQ [x s]; apply PQ.
Qed.
Proof using.
intros P Q PQ (x, (y, s)) nP; simpl. apply PQ. assumption.
Qed.
Proof using.
intros P Q PQ.  cofix cf. intros(x, s) a.
generalize (always_Cons x s P a); simpl; intros (a1, a2). constructor; simpl.
- apply PQ. assumption.
- apply cf. assumption.
Qed.
Proof using.
intros P Q J K PQ JK.  cofix cf. intros(x, s) un.
generalize (weak_until_Cons x s J P un); simpl. intros [Pxs | (Jxs, uns)].
- constructor 1; simpl; auto.
- constructor 2; simpl; auto.
Qed.
Proof using.
intros P Q J K PQ JK s unJP.
induction unJP.
- apply U0, PQ; assumption.
- apply U_next.
* apply JK; assumption.
* assumption.
Qed.
Proof using.
intros P Q J K PQ JK.
cofix cf. intros [x s] rl.
generalize (release_Cons x s J P rl); simpl.
intros [Pxs rlCJP].
case rlCJP; intros rlJP.
- apply R0.
* apply PQ; assumption.
* apply JK; assumption.
- apply R_tl.
* apply PQ; assumption.
* simpl.
apply cf. assumption.
Qed.
Proof using.
intros P Q J is_inv JPQ s Js ev.
apply (eventually_trans P Q J is_inv); try assumption.
intros; constructor 1. apply JPQ; assumption.
Qed.
Proof using.
intros P Q PQ s.
apply (eventually_monotonic P Q True_tl); auto.
Qed.
Proof using.
intros P Q impl.
apply always_monotonic.
apply eventually_monotonic_simple.
assumption.
Qed.
Proof using.
intros until 1.
intro H_eventually.
induction H_eventually.
- apply E0.
destruct s.
firstorder using always_Cons.
- eauto using E_next, always_invar.
Qed.
Proof using.
intros.
eapply always_monotonic
with (P := always P /\_ eventually Q) (Q := eventually (P /\_ Q)).
- intros.
unfold and_tl in * |-.
firstorder using cumul_eventually_always.
- eapply always_and_tl; eauto using always_always.
Qed.

(** This theorem is an analog of eventually_monotonic. *)
Lemma inf_often_monotonic_invar :
forall (invariant P Q : infseq T -> Prop),
(forall s,
invariant s ->
P s ->
Q s) ->
forall ex,
always invariant ex ->
inf_often P ex ->
inf_often Q ex.