Program Definition mkPred {A} `{ageable A} (p:A -> Prop) : pred A :=
fun x => forall x', necR x x' -> p x'.
Next Obligation.
repeat intro.
apply H1.
apply rt_trans with a'; auto.
apply rt_step; auto.
Qed.
(* The semantic notion of entailment. *)
Definition derives {A} `{ageable A} (P Q:pred A) := forall a:A, P a -> Q a.
Arguments derives [A] [H] _ _.
(* "valid" relations are those that commute with aging.  These relations are the ones that can be turned into modalities. *)
Definition valid_rel {A} `{ageable A} (R:relation A) : Prop :=
commut A age R /\ commut A R age.
(* A modaility is a valid relation *)
Definition modality {A} `{ageable A} := { R:relation A | valid_rel R }.
(* More black magic to make the definition of modaility mostly opaque. *)
Definition app_mode {A} `{ageable A} (m:modality) : A -> A -> Prop := proj1_sig m.
Definition mode_valid {A} `{ageable A} (m:modality) := proj2_sig m.
Global Opaque modality.
Coercion app_mode : modality >-> Funclass.
(* commutivity facts for the basic relations *)

(* Specifications: *)
Lemma valid_rel_commut_later1 {A} `{ageable A} : forall R,
valid_rel R ->
commut A laterR R.
Lemma valid_rel_commut_later2 {A} `{ageable A} : forall R,
valid_rel R ->
commut A R laterR.
Lemma valid_rel_commut_nec1 {A} `{ageable A} : forall R,
valid_rel R ->
commut A necR R.
Lemma valid_rel_commut_nec2 {A} `{ageable A} : forall R,
valid_rel R ->
commut A R necR.
Lemma valid_rel_age {A} `{ageable A} : valid_rel age.
Lemma valid_rel_later {A} `{ageable A} : valid_rel laterR.
Lemma valid_rel_nec {A} `{ageable A} : valid_rel necR.
Definition ageM {A} `{ageable A} : modality
:= exist _ age valid_rel_age.