Section Safety.
Definition rel X := X -> X -> Prop.
Variable X : Type.
Variable R : rel X.
Inductive safeN : nat -> X -> Prop :=
| safeO : forall x, safeN 0 x
| safeS : forall n x x', R x x' -> safeN n x' -> safeN (S n) x.
Definition safeN' n f : Prop := forall i, i < n -> R (f i) (f (1 + i)).
(** Relating [safeN] to [safeN'] (everything is finite, no axioms) *)
Proof with auto with *.
split.
- revert x; induction n; intros x Safe.
+ exists (fun _ => x); split; auto.
inversion 1.
+ inversion Safe as [ | ? ? x' Step Safe']; subst.
destruct (IHn x' Safe') as (f' & <- & IH).
exists (fun n => match n with O => x | S n => f' n end).
split; auto.
intros [|i] Hi; simpl...
- intros (f & <- & Sf).
replace 0 with (n - n)...
assert (L : n <= n)... revert L.
generalize n at 1 3 5; intros i Hi; induction i. apply safeO.
apply safeS with (f (n - i))...
replace (n - i) with (1 + (n - S i))...
Qed.
(** Coinductive safety & corresponding Knaster-Tarski definition *)
CoInductive safe : X -> Prop :=
safe_cons : forall x x', R x x' -> safe x' -> safe x.
Definition stable (P : X -> Prop) := forall x, P x -> exists x', R x x' /\ P x'.
Definition kt_safe x := exists P, P x /\ stable P.
(** Proving that [safe'] implies [safe] (the reverse implication only holds if we replace [f] with a coinductive stream) *)
Definition safe' f := forall i, R (f i) (f (1 + i)).
(** From [safe], we can derive a function assumming the functional axiom of choice (but we don't need choice to prove [safe]) *)
split.
- intros a x px; eauto.
- intros a (x, px); apply (a x px).
Qed.

Lemma konigsafe x : (forall P, P \/ ~P) -> (forall x, finite (R x)) -> (forall n, safeN n x) -> safe x.