Section ITERATION.
Variables A B: Type.
Variable step: A -> B + A.
Definition num_iterations := 1000000000000%positive.
(** The simple definition of bounded iteration is: << Fixpoint iterate (niter: nat) (a: A) {struct niter} : option B := match niter with | O => None | S niter' => match step a with | inl b => b | inr a' => iterate niter' a' end end. >> This function is structural recursive over the parameter [niter] (number of iterations), represented here as a Peano integer (type [nat]). However, we want to use very large values of [niter].  As Peano integers, these values would be much too large to fit in memory.  Therefore, we must express iteration counts as a binary integer (type [positive]). However, Peano induction over type [positive] is not structural recursion, so we cannot define [iterate] as a Coq fixpoint and must use Noetherian recursion instead. *)
Definition iter_step (x: positive)
(next: forall y, Plt y x -> A -> option B)
(s: A) : option B :=
match peq x xH with
| left EQ => None
| right NOTEQ =>
match step s with
| inl res => Some res
| inr s'  => next (Pos.pred x) (Ppred_Plt x NOTEQ) s'
end
end.
Definition iter: positive -> A -> option B := Fix Plt_wf iter_step.
(** The [iterate] function is defined as [iter] up to [num_iterations] through the loop. *)
Definition iterate := iter num_iterations.
(** We now prove the invariance property [iterate_prop]. *)
Variable P: A -> Prop.
Variable Q: B -> Prop.
Hypothesis step_prop:
forall a : A, P a ->
match step a with inl b => Q b | inr a' => P a' end.

Lemma iterate_prop:
forall a b, iterate a = Some b -> P a -> Q b.