(* Definitions of the basic modalities.
 *)
Definition ageM {A} `{ageable A} : modality
  := exist _ age valid_rel_age.Definition laterM {A} `{ageable A} : modality
  := exist _ laterR valid_rel_later.(* Definitions of the basic propositional conectives.
 *)

(* Lifting pure mathematical facts to predicates *)

Program Definition prop {A} `{ageable A}  (P: Prop) : pred A := (fun _  => P).Definition TT {A} `{ageable A}: pred A := prop True.Definition FF  {A} `{ageable A}: pred A := prop False.Program Definition imp {A} `{ageable A} (P Q:pred A) : pred A :=
   fun a:A => forall a':A, necR a a' -> P a' -> Q a'.Program Definition orp {A} `{ageable A} (P Q:pred A) : pred A :=
   fun a:A => P a \/ Q a.Program Definition andp {A} `{ageable A} (P Q:pred A) : pred A :=
   fun a:A => P a /\ Q a.(* Universal and exp quantification
 *)

Program Definition allp {A} `{ageable A} {B: Type} (f: B -> pred A) : pred A
  := fun a => forall b, f b a.Program Definition exp {A} `{ageable A} {B: Type} (f: B -> pred A) : pred A
  := fun a => exists b, f b a.(* Definition of the "box" modal operator.  This operator turns
   modalities (relations) into a "necessarily" type operator.
 *)

Program Definition box {A} `{ageable A} (M:modality) (P:pred A) : pred A :=
  fun a:A => forall a', M a a' -> P a'.(* Definition of the "diamond" modal operator.  This operator
   turns modalities into a "possibly" type operator.  _However_,
   note that this is NOT the boolean dual to "box", as usually
   found in accounts of modal logic. Instead, this is the
   "proof-theoretic" dual as found in Restall's "A Introduction
   to Substructural Logic" (2000).
 *)

Program Definition diamond {A} `{ageable A} (M:modality) (P:pred A) : pred A :=
  fun a:A => exists a', M a' a /\ P a'.Definition boxy {A} `{ageable A} (m: modality) (p: pred A): Prop :=  box m p = p.Notation "'!!' e" := (prop e) (at level 25) : pred.

(* Specifications: *)
Lemma pred_ext' {A} `{ageable A}: forall (p1 p2:pred A), app_pred p1 = app_pred p2 -> p1 = p2.
Lemma pred_ext : forall A `{ageable A} (P Q:pred A), derives P Q -> derives Q P -> P = Q.
Lemma andp_dup {A}{agA: ageable A}: forall P: pred A, P && P = P.
Lemma boxy_i {A} `{ageable A}: forall (Q: pred A) (M: modality), reflexive _ M -> (forall w w', M w w' -> Q w -> Q w') -> boxy M Q.
Lemma ruleNec {A} `{ageable A} : forall M (P:pred A), derives TT P -> derives TT (box M P).
Lemma box_refl_trans {A} `{ageable A}: forall (m:modality) p, reflexive _ m -> transitive _ m -> box m (box m p) = box m p.
Lemma box_and {A} `{ageable A}: forall R (P Q:pred A), box R (P && Q) = box R P && box R Q.
Lemma diamond_or {A} `{ageable A} : forall R (P Q:pred A), diamond R (P || Q) = diamond R P || diamond R Q.
Lemma TT_boxy {A} `{ageable A} : forall M, boxy M TT.
Lemma TT_and {A} `{ageable A} : forall P, TT && P = P.
Lemma andp_comm {A} `{ageable A} : forall P Q, P && Q = Q && P.
Lemma andp_assoc {A} `{ageable A} : forall P Q R, (P && Q) && R = P && (Q && R).
Lemma FF_and : forall {A} `{ageable A} (P:pred A), FF && P = FF.
Lemma boxy_e {A} `{H : ageable A}: forall (M: modality) P, boxy M P -> forall w w', app_mode M w w' -> P w -> P w'.
Lemma boxy_andp {A} `{H : ageable A}: forall (M: modality) , reflexive _ (app_mode M) -> forall P Q, boxy M P -> boxy M Q -> boxy M (P && Q).
Lemma boxy_disjunction {A} `{H : ageable A}: forall (M: modality) , reflexive _ (app_mode M) -> forall P Q, boxy M P -> boxy M Q -> boxy M (P || Q).
Lemma boxy_exp {A} `{agA : ageable A}: forall (M: modality) T (P: T -> pred A), reflexive _ (app_mode M) -> (forall x, boxy M (P x)) -> boxy M (exp P).
Lemma boxy_prop {A} `{H : ageable A}: forall (M: modality) P, reflexive _ (app_mode M) -> boxy M (prop P).
Lemma boxy_TT {A} `{H : ageable A}: forall (M: modality), reflexive _ (app_mode M) -> boxy M TT.
Lemma boxy_FF {A} `{H : ageable A}: forall (M: modality), reflexive _ (app_mode M) -> boxy M FF.
Lemma TT_i {A} `{ageable A}: forall w: A, app_pred TT w.
Lemma boxy_allp {A} `{agA : ageable A}: forall (M: modality) (B: Type) F, reflexive _ (app_mode M) -> (forall (x:B), boxy M (F x)) -> boxy M (allp F).