(* A "pre-predicate" is hereditary iff whenever it is
   true at world a, it is also true at all worlds
   accessable from a via R.
 *)
Definition hereditary {A} (R:A->A->Prop) (p:A->Prop) :=
  forall a a':A, R a a' -> p a -> p a'.(* A predicate is a hereditary pre-predicate *)
Definition pred (A:Type) {AG:ageable A} :=
  { p:A -> Prop | hereditary age p }.(* Here is some junk that makes the definition of "pred" opaque
   to most tactics but still allows the "Program" extension to
   see it is a subset type.  The coercion is sugar that allows us to use
   predicates easily.
 *)
Definition app_pred {A} `{ageable A} (p:pred A) : A -> Prop := proj1_sig p.Definition pred_hereditary `{ageable} (p:pred A) := proj2_sig p.

(* Specifications: *)
Lemma nec_hereditary {A} `{ageable A} (p: A -> Prop) : hereditary age p -> forall a a':A, necR a a' -> p a -> p a'.
Lemma pred_nec_hereditary {A} `{ageable A} (p:pred A) : forall a a':A, necR a a' -> p a -> p a'.