Section alt_rect2.
Variable P: T -> Type.
Variable Q: ne_list.L T -> Type.
Variable Pleaf: forall n, P (Leaf n).
Variable Pnode: forall l, Q l -> P (Node l).
Variable Qone: forall t, P t -> Q (ne_list.one t).
Variable Qcons: forall t l, P t -> Q l -> Q (ne_list.cons t l).
Fixpoint alt_rect2 (t: T): P t :=
match t return P t with
| Leaf x => Pleaf x
| Node l => Pnode ((fix F (l: ne_list.L T) :=
match l return Q l with
| ne_list.one t => Qone (alt_rect2 t)
| ne_list.cons x y => @Qcons x y (alt_rect2 x) (F y)
end) l)
end.
End alt_rect2.
Definition alt_ind2
(P: T -> Prop) (Q: ne_list.L T -> Prop)
(Pleaf: forall n, P (Leaf n))
(Pnode: forall l, Q l -> P (Node l))
(Qone: forall t, P t -> Q (ne_list.one t))
(Qcons: forall t l, P t -> Q l -> Q (ne_list.cons t l)): forall t, P t
:= alt_rect2 P Q Pleaf Pnode Qone Qcons.
Definition alt_rec2
(P: T -> Set) (Q: ne_list.L T -> Set)
(Pleaf: forall n, P (Leaf n))
(Pnode: forall l, Q l -> P (Node l))
(Qone: forall t, P t -> Q (ne_list.one t))
(Qcons: forall t l, P t -> Q l -> Q (ne_list.cons t l)): forall t, P t
:= alt_rect2 P Q Pleaf Pnode Qone Qcons.
Fixpoint head (t: T): E :=
match t with
| Leaf e => e
| Node l => head (ne_list.head l)
end.
Inductive In (e: E): T -> Prop :=
| InLeaf: In e (Leaf e)
| InNode l: InL e l -> In e (Node l)
with InL (e: E): ne_list.L T -> Prop :=
| InOne t: In e t -> InL e (ne_list.one t)
| InHead t l: In e t -> InL e (ne_list.cons t l)
| InTail t l: InL e l -> InL e (ne_list.cons t l).

Lemma InL_map_inv (Q: Set) (e: E) (f: Q -> T) (l: ne_list.L Q):
InL e (ne_list.map f l) -> exists e', In e (f e') /\ List.In e' (ne_list.to_plain l).