Section LEX_ORDER.
Variable A: Type.
Variable B: Type.
Variable ordA: A -> A -> Prop.
Variable ordB: B -> B -> Prop.
Inductive lex_ord: A*B -> A*B -> Prop :=
| lex_ord_left: forall a1 b1 a2 b2,
ordA a1 a2 -> lex_ord (a1,b1) (a2,b2)
| lex_ord_right: forall a b1 b2,
ordB b1 b2 -> lex_ord (a,b1) (a,b2).
End LEX_ORDER.
(** * Nonempty lists *)
Inductive nlist (A: Type) : Type :=
| nbase: A -> nlist A
| ncons: A -> nlist A -> nlist A.
Definition nfirst {A: Type} (l: nlist A) :=
match l with nbase a => a | ncons a l' => a end.
Fixpoint nlast {A: Type} (l: nlist A) :=
match l with nbase a => a | ncons a l' => nlast l' end.
Fixpoint nIn {A: Type} (x: A) (l: nlist A) : Prop :=
match l with
| nbase a => a = x
| ncons a l => a = x \/ nIn x l
end.
Inductive nlist_forall2 {A B: Type} (R: A -> B -> Prop) : nlist A -> nlist B -> Prop :=
| nbase_forall2: forall a b, R a b -> nlist_forall2 R (nbase a) (nbase b)
| ncons_forall2: forall a l b m, R a b -> nlist_forall2 R l m -> nlist_forall2 R (ncons a l) (ncons b m).

Lemma nlist_forall2_imply:
forall (A B: Type) (P1: A -> B -> Prop) (l1: nlist A) (l2: nlist B),
nlist_forall2 P1 l1 l2 ->
forall (P2: A -> B -> Prop),
(forall v1 v2, nIn v1 l1 -> nIn v2 l2 -> P1 v1 v2 -> P2 v1 v2) ->
nlist_forall2 P2 l1 l2.