Section StepRelations.
Variable A : Type.
Variable trace : Type.
Definition step_relation := A -> A -> list trace -> Prop.
Inductive refl_trans_1n_trace (step : step_relation) : step_relation :=
| RT1nTBase : forall x, refl_trans_1n_trace step x x []
| RT1nTStep : forall x x' x'' cs cs',
step x x' cs ->
refl_trans_1n_trace step x' x'' cs' ->
refl_trans_1n_trace step x x'' (cs ++ cs').
Proof using.
intros.
induction H; simpl; auto.
concludes.
rewrite app_ass.
constructor 2 with x'; auto.
Qed.
Definition inductive (step : step_relation) (P : A -> Prop)  :=
forall (a a': A) (os : list trace),
P a ->
step a a' os ->
P a'.
Proof using.
unfold inductive. intros.
induction H1; auto.
forwards; eauto.
Qed.
Definition inductive_invariant (step : step_relation) (init : A) (P : A -> Prop) :=
P init /\ inductive step P.
Definition reachable step init a :=
exists out, refl_trans_1n_trace step init a out.
Definition true_in_reachable step init (P : A -> Prop) :=
forall a,
reachable step init a ->
P a.
Proof using.
intros. unfold true_in_reachable, reachable in *.
intros. break_exists.
match goal with H : refl_trans_1n_trace _ _ _ _ |- _ => induction H end;
intuition eauto.
match goal with H : P _ -> _ |- _ => apply H end;
intros; break_exists;
match goal with H : forall _ _ _, step _ _ _ -> _ |- _ => eapply H end;
eauto; eexists; econstructor; eauto.
Qed.
Proof using.
unfold inductive_invariant, true_in_reachable, reachable, inductive in *. intros.
break_exists.
match goal with H : refl_trans_1n_trace _ _ _ _ |- _ => induction H end;
intuition eauto.
Qed.
Inductive refl_trans_n1_trace (step : step_relation) : step_relation :=
| RTn1TBase : forall x, refl_trans_n1_trace step x x []
| RTn1TStep : forall x x' x'' cs cs',
refl_trans_n1_trace step x x' cs ->
step x' x'' cs' ->
refl_trans_n1_trace step x x'' (cs ++ cs').

Lemma RTn1_step :
forall (step : step_relation) x y z l l',
step x y l ->
refl_trans_n1_trace step y z l' ->
refl_trans_n1_trace step x z (l ++ l').