(* author: Jean-Christophe Filliâtre *)
(** Correctness proof of Floyd's cycle-finding algorithm, also known as the "tortoise and the hare"-algorithm (see http://en.wikipedia.org/wiki/Floyd's_cycle-finding_algorithm)  If $f:A\rightarrow A$ is a function over a finite set $A$, then the iterations of $f$ from $x_0\in A$ will ultimately cycle. The following code finds out an integer $m$ such that $f^m(x_0)=f^{2m}(x_0)$ : << let rec race m x y = if x = y then m else race (m+1) (f x) (f (f y)) in race 1 (f x0) (f (f x0)) >> The difficulty is to prove $f$'s termination. *)
Require Export Arith.
Require Export Omega.
Open Scope nat_scope.
(** Let [f] be a function over a set [A] *)
Parameter A : Set.
Parameter eq_A_dec : forall (x y:A), {x=y}+{~x=y}.
Parameter f : A -> A.
Parameter x0 : A.
(** We consider the sequence $x_i = f^i(x_0)$ *)
Fixpoint x (i:nat) { struct i } : A := match i with
| O => x0
| S j => f (x j)
end.
(** We assume this sequence cycles after [lambda+mu] iterations, [mu] being the length of the cycle (we actually don't require [lambda] and [mu] to be minimal, because it is not needed for the remaining of the proof *)
Parameter lambda : nat.
Parameter mu : nat.
(** Hilbert's epsilon operator. *)
Parameter epsilon : (nat -> Prop) -> nat.

Axiom epsilon_spec : forall P, ex P -> P (epsilon P).