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').
Proof using.
intros.
induction H0.
- rewrite app_nil_r. rewrite <- app_nil_l.
econstructor.
constructor.
auto.
- concludes.
rewrite <- app_ass.
econstructor; eauto.
Qed.
Proof using.
intros.
induction H.
- constructor.
- eapply RTn1_step; eauto.
Qed.
Proof using.
intros.
induction H.
- simpl. rewrite <- app_nil_r. econstructor; eauto. constructor.
- concludes. rewrite app_ass.
econstructor; eauto.
Qed.
Proof using.
intros.
induction H.
- constructor.
- eapply RT1n_step; eauto.
Qed.
Proof using.
intros.
find_apply_lem_hyp refl_trans_1n_n1_trace.
eapply refl_trans_n1_trace_ind; eauto.
intros. eapply H0; eauto using refl_trans_n1_1n_trace, RT1n_step.
Qed.

Theorem true_in_reachable_elim :
forall (step : step_relation) init (P : A -> Prop),
true_in_reachable step init P ->
(P init) /\
(forall a a' out,
step a a' out ->
reachable step init a ->
P a ->
P a').