Infix "<p" := (@prefix _) (at level 70, no associativity).Implicit Types (l ll : list X).Fact length_nil : length (@nil X) = 0.Fact length_cons x l : length (x::l) = S (length l).Fixpoint list_an a n :=
    match n with 
      | 0   => nil
      | S n => a::list_an (S a) n
    end.Fact list_an_S a n : list_an a (S n) = a::list_an (S a) n.Fact list_an_plus a n m : list_an a (n+m) = list_an a n ++ list_an (n+a) m.Fact list_an_length a n : length (list_an a n) = n.Fact list_an_spec a n m : In m (list_an a n) <-> a <= m < a+n.Fact map_S_list_an a n : map S (list_an a n) = list_an (S a) n.Fact list_an_app_inv a n l r : list_an a n = l++r -> l = list_an a (length l) /\ r = list_an (a+length l) (length r).Definition list_fun_inv X (l : list X) (x : X) : { f : nat -> X | l = map f (list_an 0 (length l)) }.Fact list_upper_bound (l : list nat) : { m | forall x, In x l -> x < m }.Definition list_injective (ll : list X) :=  forall l a m b r, ll = l ++ a :: m ++ b :: r -> a <> b.Fact in_list_injective_0 : list_injective nil.Fact in_list_injective_1 x ll : ~ In x ll -> list_injective ll -> list_injective (x::ll).Fact list_injective_inv x ll : list_injective (x::ll) -> ~ In x ll /\ list_injective ll.

Theorem list_injective_rect l : list_injective l -> P l.