(* we can remove the need for functional extensionality, at the
   expense of heavier definitions and proofs, with [m |= P] defined as
   [forall m', eqmap m m' -> P m'] instead of [P m] *)

(*+ Syntax *)

Definition instruction := C.(*+ General results about safety *)

Definition Rel X := X -> X -> Prop.Inductive star {X} (R : Rel X) : Rel X :=
  | star_refl x : star R x x
  | star_cons x y z : R x y -> star R y z -> star R x z.Inductive star {X} (R : Rel X) : Rel X :=
  | star_refl x : star R x x
  | star_cons x y z : R x y -> star R y z -> star R x z.Inductive star {X} (R : Rel X) : Rel X :=
  | star_refl x : star R x x
  | star_cons x y z : R x y -> star R y z -> star R x z.Definition safe {X} (R : Rel X) x := forall y, star R x y -> exists z, R y z.

(* Specifications: *)
Lemma safe_R {X} (R : Rel X) x y : safe R x -> R x y -> safe R y.
Lemma safe_det {X} (R : Rel X) x y : safe R y -> R x y -> (forall y', R x y' -> y = y') -> safe R x.
Lemma safe_selfloop {X} (R : Rel X) x : R x x -> (forall y, R x y -> y = x) -> safe R x.