(* 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.

Lemma andp_assoc {A} `{ageable A} : forall P Q R, (P && Q) && R = P && (Q && R).