End PROD'.
Fixpoint composeOptN (A: Type) (f: A -> option A)
(n: nat) (w: A) {struct n} : option A :=
match n  with
| S n' => match f w with Some w' => composeOptN A f n' w' | None => None end
| O => Some w
end.
Arguments composeOptN [A] _ _ _.
Definition ageN {A} `{ageable A}: nat -> A -> option A := composeOptN age1.

(* Specifications: *)
Lemma ageN1  {A} `{ageable A}: ageN 1 = age1.
Lemma ageN_compose {A} `{agA : ageable A}:
forall a b c phi1 phi2 phi3,ageN a phi1 = Some phi2 ->
ageN b phi2 = Some phi3 ->  (a+b=c)%nat ->  ageN c phi1 = Some phi3.
Lemma ageN_compose' {A} `{agA : ageable A}:
forall a b phi1 phi3,
ageN (a+b)%nat phi1 = Some phi3 -> exists phi2, ageN a phi1 = Some phi2 /\ ageN b phi2 = Some phi3.
Lemma necR_evolve {A} `{agA : ageable A}:
necR = fun (phi phi': A) => exists n, ageN n phi = Some phi'.
Lemma age_noetherian  {A} `{ageable A}: forall phi, exists n, ageN n phi = None.
Lemma predicate_max:
forall (F: nat -> Prop) (Fdec: forall n, {F n}+{~ F n}) n,
F 0%nat ->
~ F n ->
exists i, F i /\ (i<n)%nat /\ ~ F (S i).
Lemma age_noetherian'  {A} `{agA : ageable A}:
forall phi, exists! n, exists phi', ageN n phi = Some phi' /\ age1 phi' = None.
Lemma ageable_ext:
forall A (B C: ageable A),
@age1 _ B = @age1 _ C -> @level _ B = @level _ C -> B=C.
Lemma necR_linear {A} `{H : ageable A}:
forall {a b c}, necR a b -> necR a c -> necR b c \/ necR c b.
Lemma necR_linear' {A} `{H : ageable A}:
forall {a b c}, necR a b -> necR a c -> level b = level c -> b=c.
Lemma laterR_necR {A} `{agA : ageable A}:
forall {x y}, laterR x y -> necR x y.
Lemma necR_refl {A} `{H : ageable A}:
forall phi, necR phi phi.