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).

(* Specifications: *)
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.
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.