(*  The order on the lists is not lexicographic! It's Every element is smaller or equal. ALSO : surprisingly, we don't need transitivity.  *)
Inductive list_ord {A} (ord: A -> A -> Prop): list A -> list A -> Prop:=
| lt_head: forall x y ls, ord x y -> list_ord ord (x::ls) (y::ls)
| lt_tail: forall x ls ls', list_ord ord ls ls' ->
list_ord ord (x::ls) (x::ls').
Inductive list_ord_part {A}
(list_ord: list A -> list A -> Prop)
(ord: A -> A -> Prop): list A -> list A -> Prop:=
| lt_head_part: forall x y ls, ord x y ->
list_ord_part list_ord ord (x::ls) (y::ls)
| lt_tail_part: forall x ls ls', list_ord ls ls' ->
list_ord_part list_ord ord (x::ls) (x::ls').
Inductive list_ord_trans {A} (ord: A -> A -> Prop): list A -> list A -> Prop:=
| lt_head_trans: forall x y ls, ord x y -> list_ord_trans ord (x::ls) (y::ls)
| lt_tail_trans: forall x ls ls', list_ord_trans ord ls ls' ->
list_ord_trans ord (x::ls) (x::ls')
| lt_all: forall x y ls ls', ord x y ->
list_ord_trans ord ls ls' ->
list_ord_trans ord (x::ls) (y::ls').
Instance list_ord_is_trans {A} (ord: relation A):
Transitive ord -> Transitive (list_ord_trans ord).
Definition trans_symprod {A B} ltA ltB : relation (A * B):=
Relation_Operators.clos_trans _ (@Relation_Operators.symprod A B ltA ltB).
(* List order annotated with length. *)
Definition ln_ord {A} (ord: (list A) -> (list A) -> Prop) n:=
fun ls1 ls2 =>
length ls1 = n /\ length ls2 = n /\ ord ls1 ls2.
Local Instance well_founded_subrelation {A}
: Proper (flip subrelation ==> impl) (@well_founded A).
Definition pair_to_list {A} (als: A *list A ): list A :=
match als with | (a, ls) => a:: ls end.
Definition comp_ord {A B} (ord:relation A) (f: B -> A): relation B:=
fun b1 b2 => ord (f b1) (f b2).

Lemma trans_symprod_length:
forall {A} (ord: relation A) x y,
trans_symprod ord (list_ord ord) x y ->
length (pair_to_list y) = length (pair_to_list x).