Section ITERATION.
Variables A B: Type.
Variable step: A -> B + A.
Definition B_le (x y: option B) : Prop := x = None \/ y = x.
Definition F_le (x y: A -> option B) : Prop := forall a, B_le (x a) (y a).
Definition F_iter (next: A -> option B) (a: A) : option B :=
match step a with
| inl b => Some b
| inr a' => next a'
end.
Fixpoint iter (n: nat) : A -> option B :=
match n with
| O => (fun a => None)
| S m => F_iter (iter m)
end.
Definition converges_to (a: A) (b: option B) : Prop :=
exists n, forall m, (n <= m)%nat -> iter m a = b.
Definition iterate (a: A) : option B :=
proj1_sig (constructive_definite_description (converges_to a) (converges_to_exists_uniquely a)).
(** Invariance property. *)
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.