Section wf_chains.
Variables (X : Type) (R : X -> X -> Prop).
Inductive chain : nat -> X -> X -> Prop :=
| in_chain_0 : forall x, chain 0 x x
| in_chain_1 : forall n x y z, R x y -> chain n y z -> chain (S n) x z.
Hint Constructors chain : core.
Fact chain_inv_0 x y : chain 0 x y -> x = y.
Fact chain_plus_inv a b x z : chain (a+b) x z -> exists y, chain a x y /\ chain b y z.
Fact chain_snoc_inv n x z : chain (S n) x z -> exists y, chain n x y /\ R y z.
Inductive chain_list : list X -> X -> X -> Prop :=
| in_chain_list_0 : forall x, chain_list nil x x
| in_chain_list_1 : forall x l y z, R x y -> chain_list l y z -> chain_list (x::l) x z.
Fact chain_chain_list n x y : chain n x y -> exists l, chain_list l x y
/\ n = length l.
Fact chain_list_chain l x y : chain_list l x y -> chain (length l) x y.
Fact chain_list_app l x y m z : chain_list l x y
-> chain_list m y z
-> chain_list (l++m) x z.

Lemma chain_list_inv l x y :
chain_list l x y -> l = nil /\ x = y
\/ exists k l', l = x::l' /\ R x k /\ chain_list l' k y.