(**************************************************************)
(*   Copyright Dominique Larchey-Wendling [*]                 *)
(*                                                            *)
(*                             [*] Affiliation LORIA -- CNRS  *)
(**************************************************************)
(*      This file is distributed under the terms of the       *)
(*         CeCILL v2 FREE SOFTWARE LICENSE AGREEMENT          *)
(**************************************************************)
Set Implicit Arguments.
Create HintDb length_db.
Tactic Notation "rew" "length" := autorewrite with length_db.
Tactic Notation "rew" "length" "in" hyp(H) := autorewrite with length_db in H.
Infix "~p" := (@Permutation _) (at level 70).
Section length.
Variable X : Type.
Implicit Type l : list X.
Fact length_nil : length (@nil X) = 0.
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.
End list_an.
Hint Rewrite list_an_length : length_db.
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 }.
Section list_injective.
Variable X : Type.
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 list_injective_inv x ll : list_injective (x::ll) -> ~ In x ll /\ list_injective ll.
Variable P : list X -> Type.
Hypothesis (HP0 : P nil).
Hypothesis (HP1 : forall x l, ~ In x l -> P l -> P (x::l)).

(* Specifications: *)
Theorem list_injective_rect l : list_injective l -> P l.
End list_injective.